记不清每一面问啥了,就按知识点分吧
Java
JVM内存区域
HashMap、CurrentHashMap
HashMap的底层是Java必问问题,传统的HashMap是数组+链表的结构,JDK1.8以后,当链表的层数超过8层,自动转为红黑树。CurrentHashMap线程安全。
String, StringBuffer, StringBuild三连
String创建后不可变,StringBuffer创建后可变,线程安全,StringBuild创建后可变,线程不安全
GC算法
复制算法为什么需要2个Survivor空间, 1个不行吗
survivor空间不够怎么办
volatile作用
synchronize底层
可重入锁底层/AQS底层
LRU底层实现
LRU底层是HashMap加双向链表
Redis
Redis的对象结构
String,List,Hash,Set,ZSet
实现对象的底层数据结构
简单动态字符串、双端链表、字典、压缩列表、整数集合、跳跃表等
SDS优点,链表、跳表的实现与复杂度
redis底层存储字符串的数据结构叫做简单动态字符串(simple dynamic string)。
比于原生的C语言中的字符串,SDS具备以下优点:
- O(1)复杂度获取字符串长度
- 杜绝缓冲区溢出 这是记录了free之后带来的好处
- 减少修改字符时内存重新分配的次数 因为预留了free长度的空间,关于空间分配,有以下两种策略:
- 空间预分配 具体分配策略是,如果SDS长度小于1MB,则分配和len相等的free,如果SDS长度大于1MB,则free=1MB。
- 惰性空间释放 当buf存储内容减少的时候,并不立即释放空间,而是通过增加free的值来把空间预留下来备用。
- 二进制安全 用len记录字符真实长度,防止因为'\0'而出现的内容提前截断
- 兼容部分C的字符串操作函数 为buf加上'\0'结尾,直接复用部分c的字符串操作函数
- 有序集合的底层 -字典与跳跃表 为什么用这两个结构
- redis为什么快
1:Redis是纯内存数据库,一般都是简单的存取操作,线程占用的时间很多,时间的花费主要集中在IO上,所以读取速度快。
2:Redis使用的是非阻塞IO,IO多路复用,使用了单线程来轮询描述符,将数据库的开、关、读、写都转换成了事件,减少了线程切换时上下文的切换和竞争。
3. Redis采用了单线程的模型,保证了每个操作的原子性,也减少了线程的上下文切换和竞争。
4. 数据结构也帮了不少忙,Redis全程使用hash结构,读取速度快,还有一些特殊的数据结构,对数据存储进行了优化,如压缩表,对短数据进行压缩存储,再如,跳表,使用有序的数据结构加快读取的速度。
5:Redis采用自己实现的事件分离器,效率比较高,内部采用非阻塞的执行方式,吞吐能力比较大。
- RDB AOF优缺点,怎么选择
这里redis问题比较深入
Linux/操作系统
内核态和用户态的切换
查看CPU使用率的命令
top命令
select poll epoll三连
IO多路复用
虚拟内存的作用
CPU二级缓存
网络
从输入url到显示网页过程, HTTPS的认证, DNS解析过程
DNS域名解析,TCP连接,HTTP请求,HTTP响应。
HTTPS
TCP三次握手,两次握手有什么问题
无法处理超时连接。
TCP UDP区别
TCP面向连接,UDP面向无连接,TCP可靠,UDP不可靠,TCP面向字节流,UDP面向数据报文
TIME_WAIT作用
使得最后一次挥手送到服务器。
如何快速复用处于TIME_WAIT的连接?
手动关闭?
数据库
- Mysql索引 hash和btree什么情况使用
- B+数优点,为什么不用红黑树
问的比较深
算法
排序一个字符串 时间要求O(n)
桶排序
最大正方形面积(不会换题)
好像是动态规化
奇数上升偶数下降的链表排序 空间要求O(1)
链表题
给一个有重复数字的数组,求集合{(a,b,c) | a+b+c=0}
双指针算法,去重比较难
udp和tcp区别
前面刷了
进程和线程区别
进程是CPU资源分配的基本单元,线程是CPU调度的基本单元
同步io和异步io区别
在同步文件IO中,线程启动一个IO操作然后就立即进入等待状态,直到IO操作完成后才醒来继续执行。而异步文件IO方式中,线程发送一个IO请求到内核,然后继续处理其他的事情,内核完成IO请求后,将会通知线程IO操作完成了。
socket通信过程
创建,绑定,监听,接收连接,断开
epoll和select
IO多路复用
堆和栈区别
1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2.堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。
redis底层数据结构
简单动态字符串、双端链表、字典、压缩列表、整数集合、跳跃表等
c语言中static全局变量,statis局部变量,statis函数变量区别
static 修饰时,该变量/函数的作用域为当前程序,不能被别的.c文件调用。
c语言函数指针和指针函数区别
函数指针,是指向一个函数的指针
指针函数是一个函数,其返回值为指针
一面小哥哥挺好的,给我挑了个很简单的代码题目 求数组深度
二面的代码题目还好 大数相加 数字用链表存的 反转后再相加就可以了 给了两个测试案例 123+1 999+1
然而二面的问题 我基本没答上来 明明数据库我才看过不久啊。。。
一面:
进程线程区别
数据库优化 为什么会用到索引
TCP 三次握手 四次挥手 滑动窗口
操作系统IPC
进程间通信
Map原理 hash计算 hash计算的包
Synchronized和volatile
代码:数组深度
二面:
Session cookie区别
Session保存在服务端,cookie保存在客户端
数据库索引 B+树
联合索引
Session保存
代码:大数相加(大数链表存储)
链表反转后再相加
mysql索引底层,b 树优点
两道算法题 二叉树高,该序列下一个比它大的数
(1)自我介绍一下
(2)I/O多路复用,说的详细一点,以及epoll的整个流程
epoll_create,epoll_wait
(3)多线程之间的通信方式
条件变量,锁,信号量
(4)线程之间的同步互斥(说了mutex-> lock_guard<mutex> -> unique_lock<mutex>为什么要这样去转变,还类比扯到了RAII,以及智能指针的想法)
锁的话还说了mutex,rw lock,spin lock的想法以及不同点
(5)写两个题,一个两个栈实现队列
以为有其他更好的想法。。。后来明白了,原来就是说没必要再存回去。。。不知道会不会翻车
(6)单链表逆置
1.TCP三次握手和四次挥手的过程
2.进程间通信的方式
3.进程、线程间同步的方式
4.锁机制、自旋锁、以及如何避免死锁
对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁
5.select、poll、epoll间的区别,epoll的两种工作模式
epoll水平触发和边缘触发
6.手写了两道代码题,一道二分查找,一道判断两个二叉树是否相等
7.哈希表避免冲突的方式
开链法,再Hash法
8.你熟悉的排序方式,以及其适合的应用场景
1.TCP三次握手四次挥手过程,需要把每个状态都表达出来
2.select、poll、epoll间的区别,epoll的两种工作模式
3.B树、B+树、跳表
这道题比较难,要基本解释出这三个数据结构
4.给了一个场景,要用布隆过滤器。让说一下如何实现布隆过滤器;
5.手写两道代码。一道二分查找,一道两个链表求交点