面试问题
项目相关
1.什么是跳表
跳表其实就是多层的有序链表,在最底层跳跃长度是1也就是普通的链表,越往上层走,跳表的下一个节点跳得越远,每一层成指数级增长。所以增删改查只需要log(N)的复杂度。
2.为什么要用跳表不用其他数据结构
- 高效的搜索操作:跳表的平均搜索时间复杂度为 O(log n),与红黑树等平衡树相当,因此在缓存中能够快速定位到需要的数据项。
- 简单的实现:跳表相对于其他平衡树(如红黑树)来说,实现相对简单,不需要复杂的旋转和着色操作,因此易于理解和实现。
- 低延迟:跳表具有良好的局部性,由于数据项存储在链表中,且链表节点在内存中是连续存储的,因此具有较低的访问延迟。
- 并发访问支持:跳表的插入和删除操作不需要全局锁定数据结构,因此更容易实现并发访问,适合高并发的分布式环境。
- 可调节性:跳表的层数可以根据需求进行调整,通过调整层数可以平衡搜索速度和空间利用率。
- 容易扩展:跳表在插入和删除操作时不需要像平衡树那样进行频繁的平衡操作,因此在分布式环境下,可以更容易地进行扩展和动态调整。
对于哈希表,因为要进行范围查询,哈希表对范围查询需要扫描整个表。而跳表不用。
3.跳表和红黑树以及平衡二叉搜索树的差别以及各自的优缺点
跳表(Skip List):
优点:
- 搜索、插入和删除操作的平均时间复杂度为 O(log n),与红黑树等平衡树相当。
- 实现相对简单,不需要复杂的旋转和着色操作。
- 支持并发操作,可以更容易地实现并发访问和修改。
缺点:
- 需要额外的空间来存储多层索引,相比于普通链表需要更多的空间。
- 插入和删除操作可能需要更新多个层次的索引,导致操作复杂度略高于普通链表。
- 不适合于对内存占用有较高要求的场景。
红黑树(Red-Black Tree):
优点:
- 平均情况下的搜索、插入和删除操作的时间复杂度为 O(log n),在绝大多数情况下表现良好。
- 通过旋转和着色操作来保持树的平衡,具有较好的平衡性。
- 实现相对成熟,被广泛应用于各种编程语言和数据结构库中。
缺点:
- 实现相对复杂,需要维护节点的颜色和旋转操作,可能会增加代码的复杂度。
- 不适合于并发环境下的高并发读写操作,可能需要额外的同步措施来保证线程安全。
- 在极端情况下(如频繁的插入和删除),可能会出现树的失衡,导致性能下降。
平衡二叉搜索树(Balanced Binary Search Tree):
优点:
- 保持树的平衡,保证了搜索、插入和删除操作的平均时间复杂度为 O(log n)。
- 相较于红黑树,平衡二叉搜索树的实现可能更简单,因为不需要特殊的节点着色规则。
- 适用于单线程和多线程环境下的数据结构需求,提供较好的性能和灵活性。
缺点:
- 部分实现可能会牺牲一些性能来保持树的平衡性,因此在某些场景下,性能可能略低于跳表或红黑树。
- 可能需要更多的空间来存储额外的平衡信息,相比于普通二叉搜索树。
- 需要谨慎选择实现方法,以避免不必要的复杂度和性能损失。
总体来说,选择合适的数据结构取决于具体的应用场景、性能要求和对平衡性的需求。跳表适用于内存较大且需要快速搜索的场景,红黑树适用于需要在高并发环境下保持平衡性的场景,而平衡二叉搜索树则提供了一种折中方案,适用于需要平衡性和灵活性的场景。
4.节点挂掉如何转移数据
每个节点保存有自己的数据和前面一个节点的数据。增删改的时候需要同时对对应节点服务器以及下一个服务器进行操作。
当A - B - C当中的A节点挂了,中心节点会通知B节点,因为B节点保存可A的备份数据,就将B节点村的A的备份数据加入到B自己的数据中,同时将B新增的数据加入到C节点保存B的备份数据中。
5.新增节点如何转移数据
在节点A - C中新增一个节点B,需要对AC中间的数据进行划分。在哈希AB之间的数据需要转移到B,此时会通知C节点将AB之间的数据传输给B,同时将A的备份数据传输给B,然后将自己的备份数据设置为AB之间的数据。
6.如何保证数据的一致性
插入删除都需要两个节点都同时修改,只有一个节点修改成功,另外一个没有修改则会进行rollback回滚。
7.一致性哈希用什么实现
使用map-红黑树实现,把服务器映射到一个int类型的变量放在map的哈希环中。
8.tcmalloc和其余的内存池有什么区别,为什么要用
tcmalloc(Thread-Caching Malloc)的特点:
- 速度更快: tcmalloc在处理小对象的分配和释放时,比glibc中的malloc(ptmalloc)快很多。例如,ptmalloc在一台2.8GHz的P4机器上执行一次小对象malloc及free大约需要300纳秒,而tcmalloc同样的操作大约只需要50纳秒
- 减少锁竞争: tcmalloc为每个线程提供了本地缓存,这样小对象的分配几乎没有锁竞争,而大对象的分配则使用了有效的自旋锁来减少锁竞争
- 内存碎片控制: tcmalloc通过特定的策略来分配内存,有效地控制内存碎片
- 内存利用率高: tcmalloc的内存分配策略使得内存利用率比ptmalloc更高
为什么要使用tcmalloc:
- 性能提升: 对于需要频繁分配和释放内存的应用程序,tcmalloc可以显著提升性能
- 多线程优化: 在多线程环境下,tcmalloc的设计可以减少锁的竞争,提高程序的并发性能
- 内存管理: tcmalloc提供了更好的内存管理机制,减少内存碎片,并且提高了内存的利用率
总的来说,tcmalloc是为了解决标准malloc在多线程环境下性能和内存利用率的问题而设计的。如果你的应用程序在这些方面有需求,那么使用tcmalloc可能会带来好处
9.项目是用来干什么的,实际生产的作用
为了解决在高并发场景中的通过分布式横向扩展节点来处理更多的数据和请求,从而提高系统的容量和吞吐量。并且通过一致性哈希实现负载均衡,防止单个节点的性能瓶颈。
10.B/S架构和C/S架构有什么区别
B/S架构(Browser/Server,浏览器/服务器架构)和C/S架构(Client/Server,客户机/服务器架构)是两种常见的软件应用架构,它们在设计理念、用户体验、系统维护等方面有着明显的区别:
B/S架构的特点:
- 客户端简化: 用户通过浏览器访问服务器上的应用程序,无需在客户端安装额外的软件。
- 维护成本低: 应用程序的更新和维护只需要在服务器端进行,客户端自动获得更新。
- 跨平台性强: 只要设备支持浏览器,就能访问应用程序,实现跨操作系统使用。
- 扩展性好: 适合大规模分布式应用,易于扩展和升级。
- 安全性: 由于所有数据都存储在服务器上,数据安全性依赖于服务器的安全措施。
C/S架构的特点:
- 客户端功能强大: 客户端安装专门的应用程序,可以提供丰富的用户交互和处理能力。
- 响应速度快: 直接与服务器通信,减少了数据传输时间,提高了响应速度。
- 适用于局域网: 通常用于局域网环境,对网络带宽和稳定性的要求较高。
- 维护成本高: 每次应用程序更新都需要在每个客户端进行安装和配置。
- 安全性: 可以实现更细致的权限控制和数据加密,适用于对安全性要求较高的环境。
总的来说,B/S架构更适合互联网或大规模分布式的应用,而C/S架构则更适合对性能和安全性要求较高的内部网络环境
操作系统
1.进程线程协程的区别
进程(Process):
- 进程是操作系统进行资源分配和调度的基本单位,是程序执行的实例。
- 每个进程都有独立的内存空间和系统资源。
- 进程间通信需要特定的IPC机制,如管道、信号、共享内存等。
- 进程切换开销较大,但是稳定性和安全性较高。
线程(Thread):
- 线程是进程中的执行流程,是CPU调度和分派的基本单位。
- 线程共享其所属进程的内存空间和资源,但拥有独立的执行栈和程序计数器。
- 线程间的通信和数据共享更为方便,上下文切换开销小于进程。
- 线程适合于多核处理器,可以实现真正的并行计算。
协程(Coroutine):
- 协程是一种用户态的轻量级线程,其调度完全由用户控制。
- 协程拥有自己的寄存器上下文和栈,但共享线程的资源。
- 协程能够在单线程中实现多任务的并发执行,切换开销极小。
- 协程适合于I/O密集型任务,可以提高程序的并发性能。
2.协程切换需要保存哪些东西
- 程序计数器(PC):保存了下一条指令的地址。
- 栈指针(SP):指向当前栈顶的位置。
- 通用寄存器:如RAX, RBX, RCX, RDX等,这些寄存器可能保存有函数的局部变量、参数和返回值。
计算机网络
1.SYN攻击的解决方案
- 增加SYN接收队列的大小:通过调整操作系统设置,增加服务器可以处理的半开连接数,从而减轻攻击压力。
- 启用SYN Cookies:当服务器收到SYN请求时,不立即分配资源,而是通过特定算法生成一个cookie发送给客户端,在收到客户端回应的ACK包含该cookie时,才建立连接。
- 减少SYN_ACK重试次数:减少服务器对未完成握手的连接请求的重试次数,可以减少攻击者利用未完成握手的连接占用资源的机会。
- 部署防火墙或入侵检测系统:使用防火墙或入侵检测系统来识别和过滤异常的SYN包。
- 使用云服务提供商的DDoS保护:云服务提供商通常提供DDoS攻击防护服务,可以有效缓解SYN攻击带来的影响。
2.服务器有time_wait原因是什么,怎么解决
time_wait是主动断开连接方的状态,可能是由于网络问题TCP的Keep-Alive机制,直接断开连接。
- 短连接频繁建立和关闭:每当TCP连接关闭时,主动关闭连接的一方会进入
TIME_WAIT
状态,以确保所有数据包都正确完成传输。如果服务器处理了大量短暂的连接,就可能积累很多处于TIME_WAIT
状态的连接。 - 保证连接可靠终止:
TIME_WAIT
状态确保即使最后一个ACK丢失,连接也能可靠地关闭。服务器会等待足够的时间(2倍MSL,即最大报文生存时间)来确保所有旧连接的数据包都不会影响新连接。
解决 TIME_WAIT
状态过多的问题,可以采取以下措施:
- 调整TCP参数:通过修改系统参数来减少
TIME_WAIT
状态的持续时间或者允许快速回收和重用处于TIME_WAIT
状态的端口。例如,可以设置tcp_tw_reuse
和tcp_tw_recycle
为1
来允许重用和快速回收 - 使用长连接:通过设置HTTP头中的
Connection: keep-alive
,可以使连接保持打开状态,减少连接的频繁建立和关闭。 - 增加本地端口范围:通过修改
ip_local_port_range
参数,可以增加可用的本地端口范围,从而减轻TIME_WAIT
状态对端口资源的占用。 - 优化应用程序:确保应用程序正确管理其连接,避免不必要的连接关闭和重新建立。
3.IP层是怎么知道下一跳的地址的
在IP层,确定下一跳地址的过程涉及到路由表的查找。当一个IP数据包需要被转发时,路由器或主机会检查其路由表来决定数据包的下一跳地址。这里是一个简化的过程:
- 目的IP地址匹配:路由器取出数据包的目的IP地址,并与路由表中的条目进行匹配。
- 最长前缀匹配:路由器使用最长前缀匹配原则,这意味着它会选择与目的IP地址最匹配的路由条目。
- 下一跳地址:一旦找到匹配的路由条目,路由器就会使用该条目中指定的下一跳地址来转发数据包。
- ARP解析:如果下一跳是在本地网络上,路由器可能还需要使用ARP协议来解析下一跳的物理(MAC)地址。
例如,如果路由表中有一个条目指定了目的网络192.168.1.0/24
的下一跳地址为10.0.0.2
,那么所有目的地址为192.168.1.x
的数据包都会被转发到10.0.0.2
4.time_wait的作用是什么
TIME_WAIT
状态在TCP连接中有两个主要的作用:
- 确保TCP连接可靠终止:当TCP连接关闭时,
TIME_WAIT
确保最后一个ACK报文能够到达对方。如果这个ACK丢失,对方会重发FIN报文,而处于TIME_WAIT
状态的一方可以重新发送ACK来完成四次挥手过程 - 防止旧连接的数据包干扰新连接:
TIME_WAIT
确保连接关闭后足够长的时间内不会创建具有相同四元组(源IP、目的IP、源端口、目的端口)的新连接。这样可以避免网络中延迟的数据包影响新的连接
5.HTTP状态码
200~299。表示请求成功接收、理解、并完成处理。常见的有200(正常)、204(无内容)等。
300~399。表示需要客户端进一步细化请求。常见的有301(永久重定向)、302(临时重定向)、304(未修改)等。
400~499。表示客户端的请求有错误。常见的有400(无效请求)、401(未经授权)、403(禁止)、404(未找到)等。
500~599。表示服务器端出现错误。常见的有500(服务器内部错误)、502(无效网关)、503(服务不可用)等。
6.ssl和域名绑定还是和ip绑定
通常情况下,SSL证书是绑定到域名的,因为这样更方便用户记忆和访问。但在某些特殊情况下,如果网站没有域名只有IP地址,那么SSL证书也可以绑定到IP地址上。不过,需要注意的是,绑定到IP地址的SSL证书有一些限制,例如必须是公网IP,申请者必须具有管理权限,且通常只适用于机构或企业12。总的来说,域名SSL证书的使用更为普遍和灵活。
7.HTTP一定要用TCP实现码
HTTP协议通常是基于TCP实现的,因为TCP提供了可靠的、面向连接的传输服务。这意味着通过TCP传输的数据可以保证按顺序、不丢失、不重复地到达接收端。然而,随着技术的发展,HTTP/3开始采用基于UDP的QUIC协议,这表明HTTP也可以在UDP之上实现。QUIC协议旨在提高安全性和连接效率,减少延迟,特别是在移动网络和高丢包环境中2。因此,虽然HTTP最初是设计在TCP之上的,但并不是绝对必须使用TCP。任何能够提供可靠传输保证的协议理论上都可以被HTTP使用。
8.HTTP 1.0/1.1/2.0/3.0区别
HTTP1.0和HTTP1.1的区别
⻓连接
HTTP1.1 ⽀持⻓连接,每⼀个TCP连接上可以传送多个HTTP请求和响应,默认开启 Connection:Keep-Alive HTTP1.0 默认为短连接,每次请求都需要建⽴⼀个TCP连接。
缓存
HTTP1.0 主要使⽤ If-Modified-Since/Expires 来做为缓存判断的标准 。HTTP1.1 则引⼊了更多的缓存控制策略例如 Entity tag / If-None-Match 等更多可供 选择的缓存头来控制缓存策略。
管道化
基于 HTTP1.1 的⻓连接,使得请求管线化成为可能。管线化使得请求能够“并⾏”传输,但是 响应必须按照请求发出的顺序依次返回,性能在⼀定程度上得到了改善。
增加Host字段
使得⼀个服务器能够⽤来创建多个 Web 站点。
状态码
新增了24个错误状态响应码
HTTP1.1和HTTP2.0的区别
⼆进制分帧
在应⽤层 (HTTP/2.0) 和传输层 (TCP or UDP) 之间增加⼀个⼆进制分帧层,从⽽突破 HT TP1.1 的性能限制,改进传输性能,实现低延迟和⾼吞吐量。
多路复⽤(MultiPlexing)
允许同时通过单⼀的 HTTP/2 连接发起多重的请求-响应消息,这个强⼤的功能则是基于“⼆进制分帧”的特性。
⾸部压缩
HTTP1.1 不⽀持 header 数据的压缩, HTTP/2.0 使⽤ HPACK 算法对 header 的数据进⾏压缩,这样数据体积⼩了,在⽹络上传输就会更快。⾼效的压缩算法可以很⼤的压缩 header ,减少发送包的数量从⽽降低延迟。
服务端推送 (server push)
在 HTTP/2 中,服务器可以对客户端的⼀个请求发送多个响应,即服务器可以额外的向客户端 推送资源,⽽⽆需客户端明确的请求。
HTTP2.0和HTTP3.0的区别
基于UDP协议,并引入了QUIC协议来实现可靠性传输。
解决了TCP协议中的队头阻塞问题,因为QUIC允许独立的流在丢包时互不影响。
支持0-RTT连接恢复,减少了连接建立时的延迟。
队头阻塞(Head-of-Line Blocking, HOL blocking)是计算机网络中的一种性能限制现象,特别是在HTTP和TCP协议中。它发生在一个数据包(队头)被阻塞时,导致后续的所有数据包无法被处理,即使它们已经到达并准备好被处理。
9.从输⼊ URL 到⻚⾯展示到底发⽣了什么
10.三次握⼿的过程,以及为什么是三次,⽽不是四次,两次?
11.四次挥⼿的过程,以及为什么是四次?
为什么是四次挥⼿? TCP 是全双⼯通信,可以双向传输数据。任何⼀⽅都可以在数据传送结束后发出连接释放的通知, 待对⽅确认后进⼊半关闭状态。 当另⼀⽅也没有数据再发送的时候,则发出连接释放通知,对⽅确认 后才会完全关闭了 TCP 连接。 总结:两次握⼿可以释放⼀端到另⼀端的 TCP 连接,完全释放 连接⼀共需要四次握⼿
12.TCP与UDP的概念,特点,区别和对应的使⽤场景?
13.常⻅的请求⽅式?GET和POST请求的区别?
- 作⽤不同 GET⽤于从服务端获取资源 POST⼀般⽤来向服务器端提交数据
- 参数传递⽅式不同 GET请求的参数⼀般写在URL中,且只接受ASCII字符 ,POST请求参数⼀般放在请求体中,对于数据类型也没有限制
- 安全性不同 因为参数传递⽅式的不同,所以两者安全性不同,GET请求的参数直接暴露在URL中,所以更不 安全,不能⽤来传递敏感信息。
- 参数⻓度限制不同 GET传送的数据量较⼩,不能⼤于2KB。 POST传送的数据量较⼤,⼀般被默认为不受限制。
- 编码⽅式不同,GET 请求只能进⾏ URL 编码,POST ⽀持多种编码⽅式
- 幂等,意思是多次执⾏相同的操作,结果都是「相同」的。GET ⽅法就是安全且幂等的,因为它是「只读」操作,⽆论操作多少次,服务器上的数据都是安全的且每次的结果都是相同的。POST 因为是「新增或提交数据」的操作,会修改服务器上的资源,所以是不安全的,且多次提交数据 就会创建多个资源,所以不是幂等的。
14.什么是强缓存和协商缓存
缓存可以解决什么问题:
1.减少不必要的⽹络传输,节约带宽
2.更快的加载⻚⾯
3.减少服务器负载,避免服务过载的情况出现
- 强缓存:不会向服务器发送请求,直接从本地缓存中读取资源。它通过HTTP响应头中的
Expires
和Cache-Control
字段来控制。Expires
是HTTP 1.0的字段,表示资源的过期绝对时间;而Cache-Control
是HTTP 1.1的字段,通常使用max-age
来表示资源的相对有效期。如果设置了强缓存,浏览器会在缓存过期之前直接使用本地缓存的资源。
强缓存:浏览器判断请求的⽬标资源是否有效命中强缓存,如果命中,则可以直接从内存中读 取⽬标资源,⽆需与服务器做任何通讯。
Expires强缓存 :设置⼀个强缓存时间,此时间范围内,从内存中读取缓存并返回,因为 Expires 判断强缓存过期的机制是获取本地时间戳,与之前拿到的资源⽂件中的Expires字段的 时间做⽐较。来判断是否需要对服务器发起请求。这⾥有⼀个巨⼤的漏洞:“如果我本地时 间不准咋办?”所以⽬前已经被废弃了。
Cache-Control强缓存 : http1.1 中增加该字段,只要在资源的响应头上写上需要缓 存多久就好了,单位是秒。
基于 last-modified 的协商缓存 ,⾸服务器端读出⽂件修改时间缓存。
基于 ETag 的协商缓存,将原先协商缓存的⽐较时间戳的形式修改成了⽐较⽂件指纹(根 据⽂件内容计算出的唯⼀哈希值)。
- 当强缓存过期后,浏览器会向服务器发送请求,通过请求头中的
If-Modified-Since
或If-None-Match
字段询问资源是否有更新。服务器会检查这些字段:If-Modified-Since
对应于响应头中的Last-Modified
字段,表示资源的最后修改时间。If-None-Match
对应于响应头中的Etag
字段,表示资源的唯一标识符。
如果服务器判断资源没有更新,它会返回一个304状态码,告诉浏览器可以继续使用本地缓存的资源。如果资源有更新,服务器会返回新的资源和200状态码。
15.HTTPS的⼯作原理?(https是怎么建⽴连接的)TLS/SSL连接怎么建立的
- ⾸先,客户端向服务器端发送请求报⽂,请求与服务端建⽴连接。
- 服务端产⽣⼀对公私钥,然后将⾃⼰的公钥发送给CA机构,CA机构也有⼀对公私钥,然后CA机 构使⽤⾃⼰的私钥将服务端发送过来的公钥进⾏加密,产⽣⼀个CA数字证书。
- 服务端响应客户端的请求,将CA机构⽣成的数字证书发送给客户端。
- 客户端将服务端发送过来的数字证书进⾏解析(因为浏览器产商跟CA机构有合作,所以浏览器中 已经保存了⼤部分CA机构的密钥,⽤于对服务端发送过来的数字证书进⾏解密),验证这个数字 证书是否合法,如果不合法,会发送⼀个警告。如果合法,取出服务端⽣成的公钥。
- 客户端取出公钥并⽣成⼀个随机码key(其实就是对称加密中的密钥)
- 客户端将加密后的随机码key发送给服务端,作为接下来的对称加密的密钥
- 服务端接收到随机码key后,使⽤⾃⼰的私钥对它进⾏解密,然后获得到随机码key。
- 服务端使⽤随机码key对传输的数据进⾏加密,在传输加密后的内容给客户端
- 客户端使⽤⾃⼰⽣成的随机码key解密服务端发送过来的数据,之后,客户端和服务端通过对称 加密传输数据,随机码Key作为传输的密钥。
16.HTTPS与HTTP的区别
HTTP 是明⽂传输,⽽HTTPS 通过 SSL\TLS 进⾏了加密
HTTP 的端⼝号是 80,HTTPS 是 443
HTTPS 需要到 CA 申请证书
HTTP 的连接简单,是⽆状态的;HTTPS 协议是由 SSL+HTTP 协议构建的可进⾏加密传输、身 份认证的⽹络协议,⽐ HTTP 协议安全。
17.DNS是什么,及其查询过程
DNS(Domain Name System)域名管理系统,是当⽤户使⽤浏览器访问⽹址之后,使⽤的第⼀个重 要协议。DNS 要解决的是域名和 IP 地址的映射问题。
- ⾸先⽤户在浏览器输⼊URL地址后,会先查询浏览器缓存是否有该域名对应的IP地址。
- 如果浏览器缓存中没有,会去计算机本地的Host⽂件中查询是否有对应的缓存。
- 如果Host⽂件中也没有则会向本地的DNS解析器(通常由你的互联⽹服务提供商(ISP)提供) 发送⼀个DNS查询请求。
- 如果本地DNS解析器没有缓存该域名的解析记录,它会向根DNS服务器发出查询请求。根DNS服 务器并不负责解析域名,但它能告诉本地DNS解析器应该向哪个顶级域(.com/.net/.org)的 DNS服务器继续查询。
- 本地DNS解析器接着向指定的顶级域DNS服务器发出查询请求。顶级域DNS服务器也不负责具体 的域名解析,但它能告诉本地DNS解析器应该前往哪个权威DNS服务器查询下⼀步的信息。
- 本地DNS解析器最后向权威DNS服务器发送查询请求。 权威DNS服务器是负责存储特定域名和IP 地址映射的服务器。当权威DNS服务器收到查询请求时,它会查找"example.com"域名对应的IP 地址,并将结果返回给本地DNS解析器。
- 本地DNS解析器将收到的IP地址返回给浏览器,并且还会将域名解析结果缓存在本地,以便下次 访问时更快地响应。
18.TCP 的 Keepalive 和 HTTP 的 Keep-Alive 是⼀个东⻄吗?
HTTP 的 Keep-Alive,是由应⽤层(⽤户态) 实现的,称为 HTTP ⻓连接;
TCP 的 Keepalive,是由 TCP 层(内核态) 实现的,称为 TCP 保活机制;
19.TCP连接如何确保可靠性
- 序列号: TCP给每个数据包指定序列号,接收⽅根据序列号对数据包进⾏排序,并根据序列号对 数据包去重。
- 校验和: TCP将保持它⾸部和数据的校验和。这是⼀个端到端的检验和,⽬的是检测数据在传输 过程中的任何变化。如果收到报⽂的检验和有差错,TCP将丢弃这个报⽂段和不确认收到此报⽂ 段。
- 流量控制: TCP连接的每⼀⽅都有固定⼤⼩的缓冲空间,TCP的接收端只允许发送端发送接收端 缓冲区能接纳的数据。当接收⽅来不及处理发送⽅的数据,能提示发送⽅降低发送的速率,防⽌ 包丢失。TCP利⽤滑动窗⼝实现流量控制。
- 拥塞控制: 当⽹络拥塞时,减少数据的发送。
- 确认应答: 通过 ARQ 协议实现。基本原理是每发完⼀个分组就停⽌发送,等待对⽅确认。如果 没收到确认,会重发数据包,直到确认后再发下⼀个分组。
- 超时重传: 当TCP发出⼀个数据段后,它启动⼀个定时器,等待⽬的端确认收到这个报⽂ 段。如果不能及时收到⼀个确认,将重发这个报⽂段。
20.拥塞控制是怎么实现的
21.Cookie和Session是什么?有什么区别?
HTTP是无状态的协议。Cookie 和 Session 都⽤于管理⽤户的状态和身份, Cookie 通过在客户端记录信息确定⽤户 身份, Session 通过在服务器端记录信息确定⽤户身份。
Cookie
Cookie 是存储在⽤户浏览器中的⼩型⽂本⽂件,⽤于在⽤户和服务器之间传递数据。通常,服 务器会将⼀个或多个 Cookie 发送到⽤户浏览器,然后浏览器将这些 Cookie 存储在本地。
服务器在接收到来⾃客户端浏览器的请求之后,就能够通过分析存放于请求头的Cookie得到客户 端特有的信息,从⽽动态⽣成与该客户端相对应的内容。
Session
客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是 Session 。Session 主要⽤于维护⽤户登录状态、存储⽤户的临时数据和上下⽂信息等。
存储位置:Cookie 数据存储在⽤户的浏览器中,⽽ Session 数据存储在服务器上。
数据容量:Cookie 存储容量较⼩,⼀般为⼏ KB。Session 存储容量较⼤,通常没有固定 限制,取决于服务器的配置和资源。
安全性:由于 Cookie 存储在⽤户浏览器中,因此可以被⽤户读取和篡改。相⽐之下, Session 数据存储在服务器上,更难被⽤户访问和修改。
传输⽅式:Cookie 在每次 HTTP 请求中都会被⾃动发送到服务器,⽽ Session ID 通常通 过 Cookie 或 URL 参数传递。
数据库
1.数据库的两阶段提交
事务提交后,redo log 和 binlog 都要持久化到磁盘,但是这两个是独⽴的逻辑,可能出现半成功的状态,造成两 份⽇志之间的逻辑不⼀致。所以会造成主从环境的数据不⼀致性。因为 redo log 影响主库的数据,binlog 影响从库的数据,redo log 和 binlog 必须保持⼀致。
两阶段提交把单个事务的提交拆分成了 2 个阶段,分别是准备(Prepare)阶段和提交(Commit)阶段,每个阶段都 由协调者(Coordinator)和参与者(Participant)共同完成。
2.数据库索引和主键的区别
应用范畴:主键是一种特殊的索引。在数据库中为表定义主键会自动创建一个主键索引,这是唯一索引的一种特定类型,要求主键中的每个值都是唯一的。而索引是用来加快数据检索速度的,可以在非主键的列上创建。 种类:数据库中可以创建多种索引,如唯一索引、主键索引和聚集索引。主键只是其中一种,且一个表中只能有一个主键,但可以有多个索引。 创建方式:主键是通过定义PRIMARY KEY约束来创建的,且主键列不允许空值。索引则可以在需要提高查询效率的列上创建,可以是动态创建和删除的。 唯一性和空值:主键一定是唯一的,不允许重复且不允许空值。而唯一性索引也是唯一的,但允许空值(如果数据库支持)
算法以及场景题
1.n个弹幕中随机抽取k个弹幕,不允许存储,时间复杂度为O(n),保证每个弹幕抽到的概率为相同
蓄水池抽样(Reservoir Sampling)是一种用于从未知大小的数据流中随机抽取固定数量的样本的算法。以下是该算法的具体步骤:
- 初始化蓄水池: 创建一个大小为k的蓄水池(通常k是要抽取的样本数量)。
- 填充蓄水池: 从数据流中依次读取前k个元素,将它们依次放入蓄水池中。
- 处理剩余元素: 对于剩余的数据流元素(第k+1个元素及之后的元素),依次处理每个元素i。
- 处理第i个元素:
- 生成一个范围在[1, i]的随机整数j。
- 如果j小于等于k,则用第i个元素替换蓄水池中的第j个元素。
重复步骤4直到处理完所有的数据流元素。
这个算法的核心思想在于,通过在每次处理数据流中的一个新元素时,随机决定是否将其纳入样本集合,从而保证了每个元素被选中的概率相等。这种方法在不知道数据流总大小的情况下,能够以O(n)的时间复杂度和O(k)的空间复杂度完成抽样。