系列文章目录
第一篇:语言基础
第二篇:设计模式
第三篇:数据库
第四篇:计算机网络
第五篇:操作系统
第六篇:LInux
第七篇:数据结构
第八篇:智力题
[221]hashtable 扩容和如何解决冲突
1.哈希表的扩容
(1)为什么要扩容
使用链地址法封装哈希表时, 填装因子(loaderFactor)会大于1,理论上这种封装的哈希表时可以无限插入数据的但是但是随着数据量的增多,哈希表中的每个元素会变得越来越长, 这是效率会大大降低。 因此,需要通过扩容来提高效率。
(2)如何扩容
Hashtable每次扩容,容量都为原来的2倍加1,而HashMap为原来的2倍。此时,需要将所有数据项都进行修改(需要重新调用哈希函数,来获取新的位置)。 哈希表扩容是一个比较耗时的过程,但是一劳永逸。
(3)什么情况下扩容
常见的情况是在填装因子(loaderFactor) > 0.75是进行扩容。
如何解决哈希冲突
哈希冲突:不同key值产生相同的地址,
解决哈希冲突通常有开放地址法和链地址法,公共溢出区法,再散列法两种方法,分别如下:
1开放定址法
即当一个关键字和另一个关键字发生冲突时,使用某种探测技术在Hash表中形成一个探测序列,然后沿着这个探测序列依次查找下去,当碰到一个空的单元时,则插入其中。比较常用的探测方法有线性探测法,
2链地址法
采用数组和链表相结合的办法,将Hash地址相同的记录存储在一张线性表中,而每张表的表头的序号即为计算得到的Hash地址。hashmap就是用此方法解决冲突的
1开放定址法(线性探测再散列,二次探测再散列,伪随机探测再散列):一旦发生了冲突就去寻找下一个空的哈希地址,
2再哈希法:准备若干个hash函数,如果使用第一个hash函数发生了冲突,就使用第二个hash函数,第二个也冲突,使用第三个…
3链地址法
4公共溢出区法:建立一个特殊存储空间,专门存放冲突的数据。此种方法适用于数据和冲突较少的情况。
在查找时,先用给定值通过哈希函数计算出相应的散列地址后,首先 首先与基本表的相应位置进行比较,如果不相等,再到溢出表中顺序查找。
Hashtable的默认容量为11,默认负载因子为0.75(HashMap默认容量为16,默认负载因子也是0.75);
Hashtable的容量可以为任意整数,最小值为1,而HashMap的容量始终为2的n次方;
链接
[222]说说 push_back 和 emplace_back 的区别
如果要将一个临时变量push到容器的末尾,push_back()需要先构造临时对象,再将这个对象拷贝或者移动到容器的末尾,释放原临时对象。emplace_back()则直接在容器的末尾构造对象,这样就省去了拷贝的过程。
[223]STL线程不安全的情况
在对同一个容器进行多线程的读写、写操作时;
在每次调用容器的成员函数期间都要锁定该容器;
在每个容器返回的迭代器(例如通过调用begin或end)的生存期之内都要锁定该容器;
在每个在容器上调用的算法执行期间锁定该容器
[224]类模板分文件编写
[225]memcpy和strcpy的区别
strcpy针对字符串
memcpy可以是数组、对象、字符串等,需要指定长度
[226]C++11新特性
重点:智能指针、移动语义、右值引用、类型转换
具体解析
C++新特性主要包括包含语法改进和标准库扩充两个方面,主要包括以下11点:
1.语法的改进
(1)统一的初始化方法
2)成员变量默认初始化
(3) auto关键字
用于定义变量,编译器可以自动判断的类型(前提:定义一个变量时对其进行初始化),编译时候就可以推断类型,auto不能用作函数参数,在类中auto不能⽤作⾮静态成员变ᰁ量
(4) decltype 求表达式的类型