- 如何设计一个hash表,已解决冲突特别多,数据量特别大的情况。
在rehash时,采用渐进式rehash的方法,即从新开辟一个大内存区域,存放新的哈希桶,将旧桶中的值缓慢移至新桶。
- get方法:先查询旧表,若查询失败,再查询新表(o(1)),肯定在!
- set方法:直接修改新表。若还未移动旧表数据,则直接设置新表,待旧表中该数据移动时,查询到新表中包含该数据,则直接放弃。
两次握手
三次握手的功能:
- 收发双方确切准备好
- 协商初始序列号以及确定发送接受窗口大小
二次握手情况下:(缺少客户端发送的第三次ACK,即服务端发送ACK,就认为连接已经建立) 防止已失效的连接请求报文段,又传送到了服务端,服务端建立连接浪费资源
三次挥手
红黑树和B+树的区别
红黑树和AVL的区别:
插入均旋转两次,即O(1), 对于删除操作,最坏情况下,需要维护从被删除节点到根节点的所有节点平衡性,时间复杂度为O(logn)
而红黑树只需要三次旋转(非严格平衡性,) AVL搜索稳定性(因为严格平衡)要高于红黑树。 应用场景:
avl适合查询较多,删除较少的场景。
- sizeof与strlen区别
- sizeof为操作符,可以类型,函数作为参数;strlen为函数,只能以char * 作为参数,且必须包含’\0’
- sizeof与strlen的操作结果均为size_t
- sizeof:分配空间的实际字节数
- strlen: 空间中字符的数量
- sizeof编译器运行,strlen运行期执行
- sizeof不能计算动态空间的大小
char* s = "0123456789";
sizeof(s); //结果 4 ===》s是指向字符串常量的字符指针
sizeof(*s); //结果 1 ===》*s是第一个字符
strlen(s); //结果 10 ===》有10个字符,strlen是个函数内部实现是用一个循环计算到\0为止之前
strlen(*s); //结果 10 ===》错误
char s[] = "0123456789";
sizeof(s); //结果 11 ===》s是数组,计算到\0位置,因此是10+1
strlen(s); //结果 10 ===》有10个字符,strlen是个函数内部实现是用一个循环计算到\0为止之前
sizeof(*s); //结果 1 ===》*s是第一个字符
扩展:char s 与char s[]区别 【区别所在】 char s1 的s1,而指针是指向一块内存区域,它指向的内存区域的大小可以随时改变,而且当指针指向常量字符串时,它的内容是不可以被修改的,否则在运行时会报错。
char s2[]的s2 是数组对应着一块内存区域,其地址和容量在生命期里不会改变,只有数组的内容可以改变【内存模型】
+——-+ +—-+—-+—-+—-+—-+—-+
s1: | *======> | h | e | l | l | o |\0 |
+——-+ +—-+—-+—-+—-+—-+—-+
+—-+—-+—-+—-+—-+—-+
s2: | h | e | l | l | o |\0 |
+—-+—-+—-+—-+—-+—-+