面试题整理

1.通过滑动窗口协议动态调整发送速率

滑动窗口协议是一种流量控制机制,用于管理数据发送方和接收方之间的数据传输速率,以避免因发送速率过快而导致的数据包丢失或拥塞。在TCP中,通过动态调整发送端的发送窗口大小来实现这一目标。

基本原理:

  1. 发送窗口:发送端维护一个发送窗口,窗口内的序列号表示已发送但未收到确认(ACK)的数据段。窗口大小是可变的,根据网络状况和接收端的反馈进行动态调整。

  2. 接收窗口:接收端也有一个接收窗口,并通过ACK信息告知发送端其当前接收窗口的大小。这个大小反映了接收端剩余的缓冲区容量以及处理能力。

  3. 通告窗口(Advertised Window Size):接收端会在每个ACK中携带自己的接收窗口大小,发送端据此调整自己的发送窗口。

  4. 流量控制过程

    • 当接收端接收到数据并有足够的缓冲区空间时,会增大通告窗口,发送端可以发送更多的数据。
    • 如果接收端处理速度较慢或者缓冲区接近满载,则减小通告窗口,发送端相应地减少待发送的数据量。
    • 发送端始终只能发送窗口内序号的数据段,并且只有当接收到对某个数据段的ACK后,才能将对应序号从窗口移除,并向窗口前端推进(即滑动),同时可能发送新的数据段填充窗口。

示例

  • 假设初始状态下,发送端发送窗口为4个序号单位,已发送序号0、1、2、3的数据段,接收端接收窗口也为4个序号单位。
  • 接收端收到序号0的数据段并返回ACK(0),此时发送端窗口向前滑动,发送序号4的数据段。
  • 若此时接收端处理速度变慢,只接收了序号0和1的数据段,于是它发回ACK(1),同时更新通告窗口为2个序号单位。
  • 发送端接收到ACK(1)后,知道序号0和1的数据段已被接收,窗口向前滑动至序号2和3,但由于接收端通告窗口变小,因此暂时不能发送序号5和6,直到接收端处理更多数据并增大其通告窗口。

这样,通过发送端和接收端之间不断地交互窗口信息,实现了对数据传输速率的动态控制,确保网络资源的有效利用和数据传输的可靠性。

2 http2.0了解吗?和http1.1的差距?

HTTP/2是超文本传输协议(HTTP)的第二个主要版本,相比于HTTP/1.1在性能、安全性和网络效率上有显著提升。以下是HTTP/2与HTTP/1.1的主要区别:

  1. 多路复用

    • HTTP/1.1中存在队头阻塞问题,即在一个TCP连接上一次只能发送一个请求,收到响应后才能发送下一个请求。
    • HTTP/2引入了多路复用技术,允许在一个TCP连接上同时处理多个请求和响应,避免了队头阻塞现象,提高了带宽利用率和页面加载速度。
  2. 二进制分帧

    • HTTP/1.x使用基于文本的格式进行数据传输。
    • HTTP/2将所有传输的信息分割为更小的独立帧,包括header帧、数据帧等,这些帧可以交错、并行地在同一个TCP连接上传输。
  3. 头部压缩

    • HTTP/1.1中的头部信息通常会占用大量字节,尤其是在多次请求时,重复的头部字段造成不必要的带宽消耗。
    • HTTP/2引入了HPACK压缩算法对头部进行压缩,减少了冗余信息的传输,大大提升了效率。
  4. 服务器推送(Server Push)

    • 服务器在客户端请求资源后,能够主动推送预测到客户端可能需要的其他资源,无需等待客户端发起请求,提前加载资源。
  5. 优先级和依赖性

    • HTTP/2允许设置帧的优先级,客户端可以根据页面渲染顺序指定资源的优先级,让服务器能合理安排资源的发送顺序。

综上所述,HTTP/2的核心改进在于通过减少延迟、提高带宽利用效率以及更好地支持现代Web应用的特性来优化用户体验和网络资源利用。

3 服务依赖redis服务崩溃后 如何保障服务稳定性

当服务依赖的Redis服务崩溃后,保障服务稳定性的方法可以包括以下策略:

  1. 高可用架构设计

    • 部署Redis集群:采用主从复制(Replication)和哨兵模式(Sentinel)或Cluster模式构建高可用Redis集群。这样即使一个节点失效,其他节点能够自动接管服务。
    • 数据持久化:确保Redis数据定期保存到磁盘上,通过AOF(Append-only File)或RDB(Redis Database)方式,在服务恢复时可以从磁盘快速重建数据。
  2. 客户端容错处理

    • 重试机制:在客户端库中实现合理的重试逻辑,当Redis连接失败或响应超时时,可以设置一定次数的重试。
    • 失效转移:客户端应能识别并自动切换到集群中的其他在线节点。
  3. 本地缓存策略

    • 对于非关键性或者读多写少的数据,可以考虑在服务端本地使用内存或其他存储介质作为临时缓存,当Redis不可用时,服务可以从本地缓存获取数据以减少对Redis的依赖。
    • 如果有可能,设计一种机制使得在Redis宕机期间,服务可以继续运行但可能暂时失去部分功能或性能下降。
  4. 降级处理

    • 在Redis无法访问时,服务可以进入降级模式,仅提供核心功能,或者将请求暂存入队列,待Redis服务恢复后再进行处理。
  5. 监控告警与自动化恢复

    • 设置完善的监控系统检测Redis服务状态,并在服务异常时立即发送告警通知运维人员。
    • 使用自动化工具或脚本进行故障检测和自愈,如自动重启Redis服务、重新配置客户端指向新的可用节点等。
  6. 服务隔离与熔断

    • 在分布式服务框架中,可以通过服务网格或API网关实现熔断机制,当Redis服务不可用时,服务调用Redis的部分可以迅速熔断,避免整个服务因等待Redis响应而阻塞。
  7. 冗余部署和备份计划

    • 在不同的数据中心或云区域部署多个Redis实例,提高整体系统的地理冗余性。
    • 定期备份Redis数据,并确保在灾难发生时有可靠的恢复方案。

综合运用上述策略,可以在一定程度上降低Redis服务中断对整体服务稳定性的影响,确保业务持续运行。同时,还需要根据具体业务场景和技术栈选择最合适的解决方案。

4 MySQL主库挂了,处理步骤通常包括以下几个关键环节:

  1. 识别问题

    • 确认主库是否真的宕机:检查服务器状态、网络连接、系统日志以及MySQL错误日志,确定数据库服务是否运行正常。
    • 如果是硬件故障,立即联系数据中心运维团队进行硬件修复或更换。
    • 如果是软件错误导致的宕机,查看错误日志来定位问题。
  2. 快速响应与止损

    • 通知相关业务团队,并根据业务重要性决定是否执行紧急降级操作,例如关闭写入操作以防止数据不一致。
    • 对于实时性要求不高的接口,可以暂时切换到静态数据或者返回默认信息,减轻对从库的压力和用户的等待时间。
  3. 恢复主库服务

    • 尝试重启MySQL服务。如果是因为内存溢出或其他非致命错误导致的宕机,重启可能能够解决问题。
    • 若重启无效,则需要进一步分析原因,如备份恢复、日志回滚等。
  4. 使用备用资源

    • 如果有可用的热备节点,可以启动该热备节点并将其提升为主库角色(在确保数据同步的情况下)。
    • 没有热备时,可以从最近的完整备份恢复数据,并利用binlog日志将数据追赶到崩溃前的时间点,然后转换为新的主库。
  5. 从库切换

    • 根据实际情况选择一个已同步最新的从库作为新的主库,执行必要的变更,如停止复制、更改复制模式(设置为可读写),更新应用配置指向新的主库地址。
    • 同时,其他从库也需要更新其主库地址,重新开始从新的主库上同步数据。
  6. 数据一致性验证

    • 在切换完成后,对新主库的数据进行完整性及一致性校验,确保业务不受影响。
  7. 监控与优化

    • 主库恢复正常后,持续监控系统的性能和稳定性,查找宕机的根本原因并优化避免类似问题再次发生。
    • 更新高可用和容灾策略,比如改进备份策略、增强监控报警机制、增加从库数量等。
  8. 记录与复盘

    • 记录下整个处理过程,包括故障发生的原因、处理步骤、影响范围和恢复结果,用于后期的经验总结和知识传承。

在整个过程中,必须保证数据的一致性和安全性,尽量减少停机时间并尽快恢复正常服务。同时,在设计之初就应该考虑高可用架构,如采用MySQL集群(如MySQL Group Replication)、Proxy层(如MaxScale)或者其他分布式数据库方案来提高整体系统的抗风险能力。

5 反爬了解吗?反爬的几项技术在项目里面怎么实现的?

反爬技术在项目中的实现通常包括但不限于以下几个方面:

  1. User-Agent限制

    • 实现方式:服务器端检查请求头中的User-Agent字段,验证其是否来自常见的浏览器。如果发现是爬虫的标识(如自定义的或常见爬虫库默认的UA),可以拒绝响应或者返回错误信息。
    • 项目实现:在后端代码中添加对请求头进行检查的逻辑,例如在Web框架(如Django、Express等)的中间件中过滤非正常UA。
  2. IP限制与封禁

    • 实现方式:记录并统计每个IP地址的访问频率和速率,当某个IP在短时间内发送大量请求时,将其加入黑名单或暂时封禁。
    • 项目实现:使用缓存(如Redis)、数据库或其他存储服务来记录IP访问次数,并设置相应的阈值判断及处理逻辑。
  3. 验证码

    • 实现方式:为重要接口或频繁抓取的页面增加图形验证码、滑动验证码、点选验证码等形式,阻止自动化脚本的直接访问。
    • 项目实现:集成验证码生成和校验组件,通常前端负责展示验证码,后端负责接收并校验用户提交的答案。
  4. Session管理

    • 实现方式:通过Session机制控制用户的访问行为,比如登录状态验证、防止重复操作等,这有助于识别并阻止非法爬虫。
    • 项目实现:在后端配置Session管理和验证流程,确保重要操作必须经过合法身份验证才能执行。
  5. 动态加载和JavaScript渲染

    • 实现方式:网页数据部分通过AJAX动态加载或采用SPA(Single Page Application)模式,使得简单的HTTP请求无法获取完整内容。
    • 项目实现:将重要数据通过异步API提供,同时在前端用JavaScript动态填充页面,对于爬虫而言需要解析JS或模拟浏览器执行环境(如使用Selenium)。
  6. robots.txt文件

    • 实现方式:通过网站根目录下的robots.txt文件声明哪些路径不允许爬虫抓取。
    • 项目实现:无需额外编程实现,只需正确编写并上传到服务器相应位置即可。但并不是所有爬虫都会遵守robots.txt规则。
  7. 加密链接和参数混淆

    • 实现方式:对请求链接进行加密处理,或者对请求参数进行混淆,使爬虫难以构造有效请求。
    • 项目实现:在生成链接或构建请求时进行加密处理,在服务器端解密后再进行业务逻辑处理。
  8. 请求频率限制

    • 实现方式:通过限速器模块限制同一客户端(根据IP、User-Agent等特征识别)在一定时间内的请求数量。
    • 项目实现:使用令牌桶算法、漏桶算法或其他流量控制策略,在网关层或应用层实施请求频率限制。
  9. 定制反爬策略

    • 根据实际场景设计特定的反爬策略,如要求用户授权、设备指纹检测等。

总之,具体的实现方式会因不同的开发语言、框架和应用场景而有所差异,关键是结合项目的实际情况制定合适的反爬措施,并在代码层面加以实现和优化。同时,也要注意遵循法律法规,避免过度反爬导致的法律风险。

6 项目部署的服务器是单机的,请问如果是大流量高并发请求服务器怎么处理?

当您的项目部署在单机服务器上且面临大流量高并发请求时,可采取以下策略来优化性能和提高处理能力:

  1. 负载均衡与代理层

    • 即使是单机环境,也可以考虑在前端配置一个负载均衡器(如Nginx)来分发请求。虽然单机无法实现真正的分布式负载均衡,但可以利用Nginx的高性能和反向代理功能,将部分静态资源直接返回,减少后端压力。
    • Nginx可以通过配置缓存机制,对静态资源进行缓存,并能有效处理HTTP请求的并发连接。
  2. 服务器性能提升

    • 硬件升级:增加内存以支持更多的并发连接数,提升CPU性能以快速处理请求,增大硬盘I/O速度或使用SSD存储提高数据读写效率,以及增加带宽确保网络传输不成为瓶颈。
    • 软件优化:选择合适的Web服务器软件并对其进行深度调优,例如针对Nginx或Apache的配置参数调整。
  3. 应用层面优化

    • 缓存技术:使用本地缓存(如Memcached、Redis等)缓存常用数据和计算结果,降低数据库访问频率,减轻数据库压力。
    • 异步处理:对于耗时的操作采用异步处理模型,避免阻塞主线程,例如通过消息队列系统处理非实时任务。
    • 数据库优化:优化SQL查询语句,建立索引,合理设计表结构,根据业务场景考虑是否引入读写分离、主从复制等技术提高读取性能。
  4. 代码层面优化

    • 减少不必要的计算和IO操作,精简HTTP响应头大小,压缩输出内容(如Gzip),使用CDN加速静态文件加载。
    • 对于动态内容,尽可能地将其转化为静态化页面或者半静态化页面,减少动态生成次数。
  5. 限制并发连接和请求速率

    • 可以设置合理的限速规则,控制客户端在同一时间段内的请求数量,防止短时间内大量请求冲击服务器。
  6. 动静分离

    • 将静态资源托管到独立的服务或存储中,比如使用CDN服务加速静态内容的分发,减轻服务器压力。
  7. 服务降级

    • 在高并发情况下实施服务降级策略,保证核心业务不受影响,暂时舍弃非关键功能。
  8. 监控与自动扩展

    • 建立完善的监控系统,实时监控服务器的各项指标,以便在压力过大时及时预警,并根据实际情况提前准备扩容方案。

然而,单机服务器在面对极高并发请求时存在物理极限,长期应对大流量高并发的最佳解决方案通常是转向集群架构,通过水平扩展多台服务器共同分担负载,实现弹性伸缩。如果条件允许,应当考虑迁移到云服务器,并利用云服务商提供的弹性伸缩功能进行动态扩缩容。

相关推荐
OneWind2 分钟前
使用CloudFlare R2上传图片慢怎么解决
后端
River4165 分钟前
Javer 学 c++(十六):对象特性篇(上)
c++·后端
文心快码BaiduComate12 分钟前
轻松实践:用Python实现“名字大作战”游戏,表白Zulu!
前端·后端·微信小程序
bobz96512 分钟前
tc 的锁问题
后端
空想兔15 分钟前
JeecgBoot SkyWalking 分布式链路跟踪配置
后端·elasticsearch
sunbin32 分钟前
稀土掘金我要吐槽你
后端
程序员鱼皮2 小时前
我代表编程导航,向大家道歉!
前端·后端·程序员
间彧2 小时前
Spring Boot项目中如何实现Redis分布式锁
java
zjjuejin2 小时前
Maven 生命周期与插件机制
后端·maven
掘金安东尼2 小时前
AI 应用落地谈起 ,免费试用 Amazon Bedrock 的最佳时机
java·架构