在 linux 系统中,使用 task_struct 管理一个进程,其中的 files_struct 结构则负责管理进程所拥有的文件描述符信息。
struct files_struct {
...
struct fdtable *fdt; // 指向的是file结构体
struct fdtable fdtab;
...
};
表结构
CREATE TABLE `test_table` (
`id` int NOT NULL,
`name` varchar(10) NOT NULL,
`age` int NOT NULL,
`sex` tinyint NOT NULL,
`height` int NOT NULL,
PRIMARY KEY (`id`),
KEY `name_age_sex` (`name`,`age`,`sex`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE TABLE `test_table2` (
`id` int NOT NULL,
`name` varchar(10) NOT NULL,
`age` int NOT NULL,
`sex` tinyint NOT NULL,
PRIMARY KEY (`id`),
KEY `name_age_sex` (`name`,`age`,`sex`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
从表结构可知,表中有一个联合索引,由 name, age, sex 三个字段构成,有最左匹配的机制
当索引是聚集索引时(主键索引),通常如果我们使用自增值作为主键,在插入时按照主键递增的顺序进行插入,那么是不需要磁盘的随机读取的,这种方式具有高效率。
CREATE TABLE t {
a INT AUTO_INCREMENT,
b VARCHAR(30),
PRIMARY KEY(a),
KEY(b)
};
根据这个特性,我们应该优先使用自增值作为主键,而如果使用的是非自增值作为主键,那么在插入时依然造成随机读取,使总体性能大大降低
对于非聚集索引,大部分索引值有随机性,因此必定会造成大量的随机读(页分裂和B+树节点自旋等)。为了进一步提升操作非聚集索引的性能效率,Innod db 设计了insert buffer
机制,对于满足条件的非聚集索引的插入或者更新,不是每一次都直接插入到索引页中,而是先判断是否在缓冲池中,若在,则直接插入;若不在,则先放入到一个 insert buffer 对象中,再以一定的频率和情况进行 insert buffer 和辅助索引叶子节点的合并。
A* 算法的最大时间消耗在于将节点插入open_set
,因此为了最大限度的提升效率,我们的优化方向有两个,一个是优化open_set
的数据结构,而另外一个就是尽可能的减少在寻路过程中加入到open_set
中的点。
因此可行的解决的方式有:
open_set
数据结构的优化可以使用优先队列实现,如下面示例代码所示。优先队列底层的实现逻辑是二叉堆,因此时间复杂度是O(log(n))
。open_set
的依据是F
值,而如果在寻路的过程中,如果两点中间存在大阻挡,将会使得将很多无用的点塞入open_set
中,因此常见的一种做法是进行分块处理,在可绕过阻挡块处设置寻路点,这样就可以减少要搜索的点。统计 graph 图中任意两点之间的最短距离
动态规划思想:i,j 两点之间的最短距离,通过枚举中间点 k ,计算其最小值
动态方程:dp[i][j] = min(dp[i][j], dp[i][k]+dp[k][j])
时间复杂度:O(n^3)
空间复杂度:O(n^2)
最终得到的结果是所有点之间的最短距离,可以输出路径,但是效率不高,不过这种算法可以有负权路,但是不能有负权环。
Python 对于模块的导入,遵循以下的流程方式:
从上面的流程可知,导入的模块会被转换为模块对象,并存放于sys.modules
中,且是全局唯一的。
所谓的哈希表实际上就是一个数组,属于数组的一种扩展应用。一般来说是通过申请一段长度已知的数组,通过hash函数计算数据映射到数组上的下标位置。数组存储的可以是指向某个对象的指针,也可以是特定的值,从而达到O(1)
时间复杂度的检索时间。
哈希桶数在设计上优先选择素数,因为素数能够使哈希冲突的概率更低,在进行扩容时一般是以两倍大
的方式增长,然后再查找附近的素数。
以 C++ 的 unordered_map、unordered_set 为例,这两个数据结构的底层容器都是 hashtable,它定义了28
个素数作为桶容量: