腾讯-IEG游戏数据-一面凉经复盘
算法
排序有哪些
❌手撕归并排序 : 错误原因:死在二分递归的边界上,必须要[l,r]
- 我错误使用 [l,r),然后递归传入[ l,mid ) ,[ mid+1,r)
- 注意最好[l,r]且 每次mergeSort传入[l,mid] [mid+1,r]
- 同样合并有序数组中:i=l,j=mid+1,然后保证 i <=mid j<=r
八股
无
web项目
❌JWT令牌的原理 :
答:token的原理 + jwt生成头部、载荷、签名,客户端保存到本地,发送http请求时头部携带
首先了解JWT、cookies、session、token有什么区别?
cookies
的作用是:让服务器在一段时间内认识你
或保存你本地的信息
。发送请求时浏览器自动添加到http的cookies字段上。方便服务端识别并保存客户端的信息session
:服务端创建并维护的一个会话状态
,服务器创建连接后将其保存到本地,然后session通过cookies,第二次根据cookies中的session找原本的session信息token
:为了减轻服务端的存储和查询数据库压力
,服务端接收到客户端的登录消息后,签名并加密后返回密文,以后客户端的访问都在http请求头带上token,然后服务端解密算法就可以识别用户。JWT
:一种JSON格式的token
,同样是服务端签名加密后返回,客户端下一次发送的请求头带上,服务端解密后获取到用户信息,不需要收到用户信息后查找数据库来鉴权
接着可以解答上面的问题:
- JWT在服务端是怎么生成的?根据登录信息,生成
头部(token的类型和加密算法
),载荷(用户发送的登录身份信息)
,数字签名(用来验证完整性和真实性)
- JWT在客户端是怎么存储的?
存在浏览器中(localStorage
,不清理再打开还有),存在会话中(sessionStorage
,关闭当前页面就没了),cookies(带在http报文中
每次自动发送)
参考:
数据库内核
⭕数据库持久性怎么实现?
日志记录,持久化,备份和恢复
⭕数据库日志的异步刷盘怎么实现?
日志写缓冲区
:日志先写入logBuffer中,然后满了以后成批刷入,减少IO消耗原本的同步刷新是怎样的?
当发起写入操作时,当前线程执行刷入磁盘操作,将logBuffer中数据刷入到磁盘,直到刷入成功才返回并执行后序操作刷新缓冲区flushBuffer
:从logBuffer复制到flushBuffer中就认为已经刷新了,等待刷新线程刷入磁盘后台刷新线程
:缓冲区满以后 或者 定期 启动刷新线程,复制logBuffer到flushBuffer并刷入磁盘异步是怎么实现的?
当发起刷入操作,直接刷入数据到内存中的flushBuffer,然后直接返回成功并做后序的操作,等待后台异步地线程将flushBuffer中的日志刷入磁盘
❌异步刷盘后持久性还能实现吗?
答:不能,因为异步刷盘不能保证数据不丢失
- 问题1:并发写入日志后出现刷新的情况怎么解决?
flush线程开始任务前对logBuffer互斥访问
- 问题2:当复制到flushBuffer后还没刷入时发生了崩溃,能保持一致性吗?
不能,因为是对logBuffer拷贝到内存中的flushBuffer,还未刷入时断电会丢失这部分数据,因此异步刷盘获得高性能的代价是丢失持久性
- Mysql中也是根据场景,在commit或者abort时设置类似fsync的方式保证同步刷盘一定落盘成功,或者为了高性能采用异步刷盘后台线程1s刷新一次
参考:
OS
⭕fork() 的原理,哪里体现了fork分配资源?
复制堆栈段,数据段,栈段等内存布局,但是代码段是映射的父进程的代码段以节省空间
⭕fork()是把进程从1个变成2个,那么最初的进程是从哪里来的?
系统启动时先加载内核,然后通过引导程序启动初始进程init或者叫systemd进程,是整个进程树的根节点
⭕启动进程是用户态还是内核态?
systemd进程是内核直接创建的,因此是内核态进程
⭕进程和线程的关系和区别
进程是资源分配的基本单位,有独立的内存空间,创建和切换的开销比较大
线程是CPU调度的基本单位,线程是轻量级的进程,只有独立的一组寄存器,PC和栈以及ThreadLocal这样的本地存储,因此创建和切换开销更小
❌进程是通过fork创建的,linux下线程是怎么创建的?
要了解并区分内核态和用户态线程
用户态线程的创建
:用户空间的线程库pthread负责管理,内核实际上是看不见的,可以看见并操作的最小粒度是进程内核态创建线程
:系统调用clone,由内核直接负责创建、调度、资源分配
参考:
#复盘面经##腾讯##腾讯实习#