7.15 腾讯云智面经整理
JWT鉴权过程、存储位置
JWT令牌由三个部分组成:头部(Header)、载荷(Payload)和签名(Signature)。其中,头部和载荷均为JSON格式,使用Base64编码进行序列化,而签名部分是对头部、载荷和密钥进行签名后的结果。
在传统的基于会话和Cookie的身份验证方式中,会话信息通常存储在服务器的内存或数据库中。但在集群部署中,不同服务器之间没有共享的会话信息,这会导致用户在不同服务器之间切换时需要重新登录,或者需要引入额外的共享机制(如Redis),增加了复杂性和性能开销。
而JWT令牌通过在令牌中包含所有必要的身份验证和会话信息,使得服务器无需存储会话信息,从而解决了集群部署中的身份验证和会话管理问题。当用户进行登录认证后,服务器将生成一个JWT令牌并返回给客户端。客户端在后续的请求中携带该令牌,服务器可以通过对令牌进行验证和解析来获取用户身份和权限信息,而无需访问共享的会话存储。
JWT 的缺点是一旦派发出去,在失效之前都是有效的,没办法即使撤销JWT。 黑名单
服务端可以将JWT令牌通过Cookie发给浏览器,浏览器在请求服务端接口时会自动在Cookie头中带上JWT令牌,服务端对Cookie头中的JWT令牌进行检验即可实现身份验证。但它容易受到CSRF攻击的影响。
解决的方法是通过设置Cookie的SameSite属性为Strict。跨站时不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。
Cookie除了易受CSRF攻击还有XSS攻击。黑客可以通过JS脚本读取Cookie中的信息。为了防止这一点,可以设置Cookie的属性为HttpOnly。
有栈协程,无栈协程
有栈协程:每个协程都有自己的独立栈空间。栈是程序运行时用于存储局部变量、函数调用的返回地址等信息的内存区域。在有栈协程中,当协程切换时,它会保存自己的栈状态,包括栈指针、栈中的局部变量等。例如,在一个有栈协程中调用了一个深度嵌套的函数,这些函数的局部变量和调用信息都会在协程的栈上保存。当协程暂停和恢复时,这个栈状态会被完整地保存和恢复,就像一个完整的程序上下文一样。
无栈协程:没有独立的栈空间。它主要依赖于程序的主调用栈。当无栈协程运行时,它会借用当前线程的栈。这意味着无栈协程不能像有栈协程那样进行复杂的嵌套调用,因为它没有自己的栈来保存这些调用信息。例如,在一个无栈协程中,如果进行深度嵌套的函数调用,可能会导致栈溢出,因为这些调用信息都挤在主调用栈上。
讲一下线程和进程的区别?然后如果设计一个系统,然后它肯定是要多并发去执行,我是怎么去用多线程?
ACID分别指什么?
Atomicity(原子性):一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被恢复(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
Consistency(一致性):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
Isolation(隔离性):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
Durability(持久性):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
数据库是怎么去实现他这个持久性?
主要是通过 redolog 来实现事务持久性的,事务执行过程,会把对 innodb 存储引擎中数据页修改操作记录到 redolog 里,事务提交的时候,就直接把 redolog 刷入磁盘,即使脏页中途没有刷盘成功, mysql 宕机了,也能通过 redolog 重放,恢复到之前事务修改数据页后的状态,从而保障了数据不丢失。
读已提交会有什么问题
不可重复读、幻读
快速排序的原理,过程
快速排序是一种高效的分治排序算法,平均时间复杂度为O(n log n),最坏情况下为O(n²)(但可通过优化避免)。
选择哨兵,将小于哨兵的数据放在左边,大于等于的放在右边,分割递归排序,然后合并。
IO多路复用
我们还是把视角放到应用B从TCP缓冲区中读取数据这个环节来。如果在并发的环境下,可能会N个人向应用B发送消息,这种情况下我们的应用就必须创建多个线程去读取数据,每个线程都会自己调用recvfrom 去读取数据。那么此时情况可能如下图:
为了保证消息能及时读取到,那么这些线程自己必须不断的向内核发送recvfrom 请求来读取数据;
能不能提供一种方式,可以由一个线程监控多个网络请求(我们后面将称为fd文件描述符,linux系统把所有网络请求以一个fd来标识),这样就可以只需要一个或几个线程就可以完成数据状态询问的操作,当有数据准备就绪之后再分配对应的线程去读取数据,这么做就可以节省出大量的线程资源出来,这个就是IO复用模型的思路。
单个线程就可以同时处理多个网络连接。内核负责轮询所有socket,当某个socket有数据到达了,就通知用户进程。多路复用在Linux内核代码迭代过程中依次支持了三种调用,即SELECT、POLL、EPOLL三种多路复用的网络I/O模型。
epoll和select区别
三次握手最后一次失败了会发生什么?
服务端重传第二次握手
n 个数,从 n 个数里面找出三个数,然后把这三个数的和求绝对值最小。这三个数怎么找?说思路
枚举一个数,双指针另外两个数