总结了一下各大平台上的面经 以及一些自己不熟悉的

百度测开预备

mysql和redis的区别

前者是关系型数据库 后者是kv型数据库 nosql

mysql以表格形式存储数据 redis以键值对形式存储数据

前者将数据存储在磁盘当中 后者将数据存储在内存当中 所以后者的响应速度一般来说比前者快 可容忍的QPS比前者大

mysql在项目中一般用作DB层 redis一般用作缓存 中间层

mysql基于innodb 在重启之后数据不会丢失 还可以进行一定程度上的崩溃恢复 redis重启后会丢失数据 但是提供了 AOF和RDB文件来支持数据持久化

查找排名第二的成绩

1
2
3
4
select score 
from table
order by score desc
limit 1 offset 1

查询范围内的成绩

1
2
3
4
select score
from table
where score between 1 and 100
order by score desc

如何评判ai大模型的准确率

什么任务:

生成任务 分类任务 回归任务

分类任务:给出多个分类和目标物体 让ai大模型对他进行分类 并评估结果的主权内省

生成任务:使ai原创某段文字 评估该生成内容的准确性和真实性等

回归任务:给出某些特征值 让ai通过这些特征值 计算出所想要得到的目标值

如何评估代码

代码的可读性:注释 变量 命名是否规范

功能的正确性:是否正确实现了目标的功能 是否有bug或者与需求分析不同

健壮性 鲁棒性:输入边界情况的时候 是否能准确进行处理 是否处理了边界情况

模块性:有没有将一些可复用的代码抽取出来

安全性:代码是否存在安全漏洞

测试是否覆盖:是否有进行测试

测试方法有哪些

功能测试:主要关注软件是否按照需求规范进行工作 检查其是否按照预定工作

非功能测试:测试软件的安全性 是否存在性能漏洞

回归测试:在功能新增后进行测试 用于确保新增的功能不会对已有的旧功能使用的性能等造成影响

探索性测试:基于测试人员的主观判断所进行的测试

冒烟测试:测试功能是否都可以正常使用

黑盒测试:忽略程序的运行细节 只通过外部输入和输出判断程序是否正常运行

白盒测试:考虑程序的运行细节 从内部结构上 判断程序是否在正常运行

用户验收测试:乙方进行的测试 判断产品是否符合需求的测试

边界值测试:输入边界值和异常情况等 判断程序的响应是否合理且符合规范

压力测试:评估程序的性能和极端情况下的可负载能力 逐步增加资源的消耗 (通过增加请求数量等方式) 检查在高负载情况下的服务器资源运行情况

测试用例 场景:购物车

从多个角度思考

此时物品售卖状态

物品处于不可出售状态

活动物品已出售或者下架(超买超卖)

价格是否正确

设置此时有折扣活动 是否能合理满足折扣需求 如果是本店折扣和跨店折扣

可以设置开店满足单店折扣的金额 判断折扣相关代码是否正常达成效果

售卖数量是否合理

是否可以买很多件物品 单次购买的上限是多少 包括购买同样的物品次数上限和 不同物品的种类上限

是否可以购买超出当前库存数量的物品

是否可以买数量为0 或负数的单件or多件物品 是否会扣费之类

购物车容纳数量

购物车中最多可以容纳多少未买的物品

购物车中已经买了的 会不会还在购物车中显示

购物车单件物品最多可以加入多少件

是否可以加入商品状态异常的物品

能否合理跳转支付

当交易金额异常时 是否会跳转支付界面

单次交易金额的上限是多少

单次交易金额为空 是否允许

短时间内允许多少次订单的跳转和创建

支付失败的时候 购物车中的物品是否还存在 是否消失

数据一致

不同设备上登录的时候 购物车的消息是否需要同步 是否成功同步

单设别长时间未登录 购物车库存是否会消失 是否会更新

短时间内购物车更新的时候 不同设备之间的同步消耗时间

测试用例 场景:抢红包

包红包

红包的发送模式是否正常(拼手气模式和平均模式)

红包最多可以设置包多少个

红包可以设置的最大金额

红包是否可以设置0金额 或者复数金额

红包的封面是否可以自定义

红包的封面自定义存储上限

红包的自定义封面是否可以正常使用

红包的拼手气模式是否有分配几率 随机分配是否满足随机的需求

红包发出去之后 余额或者其他渠道的金额是否扣除 是先扣除还是先发出红包

红包可以包的人数是否可以是0或者负数

多次发出红包的时候 是否存在限额提醒

多次发出红包的时候 是否堆拼手气模式下的随机概念产生影响

超过了发红包的时限的时候 金额是否原路返回

是否可以连续多次发红包

红包的金额是否可以是0或负数

红包如果支持口令红包 是否具有违禁词过滤系统

红包描述输入是否存在格式限制

红包输入的字符是否能清晰可见 是否会显示乱码

红包输入的字符是否可以复制

红包输入的时候 是否允许发表情

红包输入框描述是否能为空 (最大限制是多少)

断网的时候 发红包会怎么样

余额不足的时候 还能不能发出红包

输入金额的时候小数点是否会有限制(只能单个)

包红包的时候突然取消终止 实际金额会怎么办 此时红包会怎么样

抢红包

同一时刻内多个人同时抢红包(已经超过了红包个数) 此时是否回绝抢的请求

抢红包的时候金额是否与实际金额成功对应(拼手气和平均模式下)

抢红包的时候 最多可以容纳多少个人一起抢

抢红包的时候 假如红包已经被抢完了 发起请求还能不能抢

是否存在检测机制 多个红包均在短时间内抢到(反脚本机制等)

自己发的红包自己是否可以抢

超过了红包领取实时限的红包是否可以抢

单红包抢到的值是否会为0或负数

抢红包的时候 网络突然间断开 此时会不会导致金额到账了 但是红包显示没抢

测试用例 场景:大模型问答

功能

是否可以正常问答 是否可以正常上传文件 是否可以正常上传图片

文件最多上传多少个 是否支持同时上传

是否可以上传多个不同文件类型的图片和文件

上传的文件大小是多少 图片大小上限是多少

是否可以上传空文件 空图片

是否可以仅上传图片或文件 不上传文字

是否可以同时上传文字和图片

是否符合回答的规范tokens范围内

单次会话 最多可以上传多少MB文件上限的文件和图片总量

单次会话 是否允许生成图片和文件 生成并且返回的大小限制是

是否可以在大模型侧运行代码 并返回实际运行代码和效果

发送的时候 输入框是否允许复制粘贴

发送的时候 输入框的文字数量限制是多少

发送的术后 输入框是否可以输入表情或一些特殊字符 emoji等等

大模型侧回答是否能返回表情和特殊字符

返回的表情和字符是否都能正确渲染

大模型是否具有思维链

思维链的推导尺度是否符合当前模型的平均水平

思维链中出现的思考节点是否正确

思维链中的思维推论渲染是否正确

思维链和代码块生成的是否可以选择折叠 只看返回的生成结果

大模型是否能正常解析图片和文件当中的内容

大模型的内置引擎是否正常工作 例如说OCR阅读PDF或图片上的文字等

是否提供联网搜索等功能 是否可以联网搜索

在联网搜索的时候 是否真正进行了搜索(数据是否具有实时性)

是否允许推理和联网搜索和上传图片文件这几个功能都一起使用

是否支持在上次聊过的地方重新开始聊

是否支持上下文功能并且具有上下文记忆

生成的内容是否具有条理性

生成的内容是否正常结束

输入空值是否能进行问答

输入违禁词 违禁图片 违禁文件是否能进行处理

诱导性使大模型输出违禁内容是否成功

短时间内多次上传多个文件或图片

短时间内多次调用 是否限流

终止大模型回答后 是否能继续问答 是否影响输出

是否支持切换模型

输入非法模型进行调用

切换模型后 当前模型是否还支持上传图片文件推理等功能 前端相关的选项是否关闭

切换模型时是否做权限认证

切换模型时 是否能继续上一个会话 对上下文是否有影响

单用户多端同时进行提问(单会话和多会话)

输入框是否支持直接快捷键复制粘贴图片文件等

是否支持拖拽上传文件图片

文件图片上传失败提示

提问回答失败措施(大模型侧终止访问)

提问时网络异常措施

提问时服务器错误措施

提问时刷新 关闭页面措施

提问时终止 发起二次提问

提问时开启新会话

是否支持跨会话记忆功能

是否支持手动删除更新跨会话记忆

记忆是否体现在回答中

单次请求回答的调用平均时间

单次调用的吐字效率时间

单次思维链推理的平均时间

单次上传单位大小文件的时间

单次请求吐字卡住时的兜底措施

多个平台上是否都能上传文件回答等

多个平台上是否支持其他全套的功能 前端页面显示和更新是否混乱

终止生成之后 是否可以继续生成

测试用例 场景:输入框

输入的格式限制 是否生效 是否必须含数字字符大小写字母

输入为空

输入的字数限制

输入特殊字符时是否能正常渲染

输入框是否能复制粘贴

输入框是否有浮窗提示输入格式

输入框输入不合法的时候 是否有异常提示

输入框中是否能使用撤销这些快捷键

输入框是否能输入空格和换行符

不同浏览器(不同端)是否可输入

不同浏览器 不同段是否正常渲染

是否会出现SQL注入一类问题

复制粘贴数据格式不对时 是否有提示

测试用例 场景:搜索框

功能

搜索的时候 是否可以输入非法字符 特殊字符

搜索的时候 输入的文字超过搜索上限怎么办 截断等措施有没有正常使用

搜索的时候 输入的字符为空时 会不会弹出体现 或跳转到主页面

搜索的时候 是否可以复制粘贴

搜索的时候 是否可以上传图片或者文件进行搜索

搜索的时候 是否可以使用快捷键 类似ctrlz进行撤销或者重做一类

搜索的时候 筛选条件是否可选 如果是单选框的话 会不会做到在选中其中一个的时候 另外一个默认取消选中

搜索的时候 是否可以换行 按shift+空格进行换行

搜索的时候 是否可以按回车快速跳转进行搜索

当默认搜索引擎为百度的时候 按快捷键ctrlt新开页面的时候 光标是否聚焦在搜索框当中

当在搜索页面 且搜索光标不在搜索框的时候 是否有快捷键可以重新聚焦于搜索蓝当中

是否可以按下tab+方向组合键 使当前聚焦在某个搜索框上

当网络异常的时候 此时搜索栏搜索不成功是否会返回提示

当前端页面异常的时候 重置刷新是否可以恢复页面

当后端服务器异常的时候 前端搜索页面上是否会返回提示

性能

在网络正常的前提下 单次搜素的平均耗时时间

在弱网环境下 单次搜索的平均耗时时间

输入的时候 是否存在输入的速率限制

上传图片或者文件进行搜索的时候 上传的平均速率

是否可以单次上传多张图片或者文件

上传多种类型的文件和图片

上传超大文件和图片

上传超多文件和图片

上传空文件和图片

打开搜索页面的平均耗时时间(正常网络环境和弱网环境下)

搜索历史是否云端or本地同步

压力测试 最多单位时间内 搜索引擎可以满足并处理多大的并发搜索请求

且在压力测试环境下 单次搜索时长所受到的影响

在搜索引擎的服务器添加的之后 判断当前的提升效率 当前的服务器架构下 是否呈水平拓展

安全

模拟SQL注入 在搜索框搜索 相关内容 是否能识别出来并进行处理

敏感词搜索 是否过滤 回绝搜索请求

单IP下多时间内多次进行搜索 是否进行限流

兼容性

在不同的平台上打开搜索页面 UI显示是否正确 是否能打开

在不同的页面上是否能进行正常的搜索功能

不同平台上的搜索历史是否同步

不同分辨率

在不同的页面缩放比例下 当前的UI是否正常 (布局是否正常)

页面的前端分布比例是否合适

易用性

对用户是否友好

是否有使用文档

对ai大模型上传文件设计测试用例

上传文件的测试用例 重点就是在文件这一块

上传单个文件

上传多个文件

上传不同类型的文件

上传超大的文件

上传空文件

上传名字相同的相同文件 or 名字相同的不同文件 查看系统怎么对文件内容进行校验

上传文件名文件

上传损坏文件

上传文件 测试速度

多用户同时上传文件 测试对效率的影响

上传恶意漏洞文件

上传含违禁词文件 违禁内容文件

不同端上传文件 不同浏览器上传文件(浏览器兼容性)

同一账户 多端同时上传文件(单点上传)

移动设备 平板 上传兼容

兜底策略

上传的时候网络断开

上传的时候 服务器错误

上传失败

上传用户鉴权 认证 有没有权限or额度上传文件

是否能拖拽上传

上传的方式

上传的上限是否设置

是否可以取消 上传

上传进度显示

上传异常反馈

进程和线程的区别

进程是程序运行的基本单位 是操作系统分配资源的基本单位 一个进程之中有一或多个线程

线程的颗粒度比较小 创建销毁的时候所耗费的资时空成本也比较少 因此我们会利用多线程并行运行来加快单个进程运行的效率 调优

在操作系统中 是以进程为单位分配页表 堆栈 fd 等资源的 单个进程内的所有线程共享进程下的所有资源 同时每个线程也有自己的内部缓存 即ThreadLocal等 在很多编程语言中也有体现

进程之间是独立的 单个进程的崩溃一般来说不会导致其他程序的运行崩溃

但是单个进程下的多个线程 由于是共享进程资源的 所以单个线程的崩溃有可能会导致进程直接崩溃

进程之间的数据共享是通过MQ 接口 CHANNEL等方式进行实现的

线程之间的数据共享很简单 因为它们共享共同的内存空间 只需要约定存储的位置即可 但是同时会导致线程间的竞态问题

这时候 需要利用锁 等方式实现一个同步获取

进程的颗粒度大 在上下文切换的时候 需要保存自身的页表 堆栈 所有寄存器等信息

但是多线程由于是共享同一内存空间的 所以他需要保存的信息只有自身的缓存和元信息 比进程少 所以他的上下文切换速率更加快和轻量级

输入URL的过程

将URL输入之后 需要将这个域名解析成为IP地址

整个过程是 浏览器会首先检查本地的DNS缓存 查看其中是否有对应的缓存值

如果有则直接将域名转为IP 如果没有的话 就会到DNS服务中进行查询 这个过程会是递归的 (由低级DNS服务器到高级DNS服务器)

最后获得域名对应IP后 回写DNS缓存 同时和目标IP建立一个TCP连接

连接建立后 将会发送http/https数据包到目标服务器上 并且等待得到服务器发送回来的http响应

最后浏览器根据响应更新页面或更新数据 做出对应的反馈

TCP连接关闭 一次请求结束

数据库的三范式

第一范式:每个字段中的值必须是原子的 不可再分

第二范式:表中的非主键行必须要依赖主键 假如主键是符合主键 必须两个都要依赖 不能只依赖主键的一部分 部分依赖

第三范式:表中的非主键行 不能依赖于主键以外的行 传递依赖

死锁的发生和预防

死锁产生的四个必要条件

互斥 持有资源并等待 非抢占 调用环路

预防 破坏这四个条件就可以了 编码上进行规范 破坏资源调用形成环路的条件 设置为同步获取资源

允许抢占

死锁检测和死锁恢复机制

终止产生死锁的对应线程 让他释放资源

数据库事务

ACID 原子性 持久性 隔离性 一致性

原子性 数据库执行的操作不可分 要么全部执行成功 要么全部执行失败

一致性 数据库事务执行前后的逻辑一致性

隔离性 数据库事务内部产生的修改不会影响到外部

持久性 数据库事务所执行的修改是永久性的 不会丢失

其他见另外文章

深拷贝浅拷贝

浅拷贝 只复制对象的引用 不复制对象中的子对象 原对象和拷贝对象共享子对象

深拷贝 递归复制原对象内的所有子对象到子对象之中 元对象和拷贝对象中的值相同 但并非同一对象

递归求阶乘

两方式本质一样

1
2
3
4
5
6
7
8
9
10
11
public class Main {
public static void main(String[] args) {
System.out.println(cal(10, 1));
}
public static int cal(Integer n, Integer v) {
if (n == 0) {
return v;
}
return cal(n - 1, v *= n);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Main {
static int v = 1;
public static void main(String[] args) {
cal(10);
System.out.println(v);
}
public static void cal(Integer n){
if (n == 0){
return;
}
v *= n;
cal(n - 1);
}
}

TCP/IP 栈有几层 每一层有什么协议

四层

网络接口层 应用层 网络层 传输层

网络接口层:PPP (数据链路层) 通过MAC地址进行通讯的

网络层:IP ICMP ARP RARP

IP : 表示网络地址的基本协议

ICMP : 表示网络通讯情况 (告警 报错 重连)等标志的协议

ARP : 将IP地址解析成为MAC地址

RARP : 将MAC地址封装为IP地址

传输层:TCP / UDP

TCP : 面向连接的协议 可靠但是协议相对重量级

UDP : 面向报文的协议 轻量级但是对网络稳定性等要求较高

应用层:HTTPS HTTP DNS FTP SMTP

基于TCP / UDP 基础上为了特定应用领域发展的协议

DNS : 将域名解析为IP

FTP : 文件传送协议

SMTP : 电子邮件协议

进程之间怎么通信

pipe管道

1
2
int fd[2];
pipe(fd);

本质上就是两个进程

一个进程占有管道的写口

一个进程占有管道的读口

然后通信的时候 往这个管道传数据就可以了

MQ

经典生产消费模型 通过MQ进行解耦

生产的进程产生数据之后 丢到MQ

然后让消费者进行消费即可

本质上跟pipe的流程差不多

共享内存

两个进程共享同一块内存的时候

A进程往这里写东西 B进程读即可通信

信号量

信号量本质上表示当前临界资源的数量

进程可以利用这个信号量知道现在有多少个进程获取了临界资源

条件变量

本质上就是互斥锁 & 为1的信号量 一般也用来标记临界资源

进程可以通过它得知当前的资源正在被占有中

体现在java中的volatile变量等

DNS的解析过程

键入网址搜寻的时候 首先会在本地查找对应的映射缓存

如果没有 就会到根DNS服务器当中询问域名的根路径 后者会返回对应域名后缀对应的顶级DNS服务器地址

通过访问这个顶级DNS服务器地址 本地会得知域名对应的权威服务器的地址

然后访问这个权威服务器的地址 就可以得到域名所对应的真实IP值

然后本地就可以基于这个IP来建立连接

在这一环节中 每个服务器当中都会有缓存 DNS服务器会通过缓存加快查询时的效率

TCP和UDP的区别 以及对应的应用场景

TCP是面向连接的协议 数据会在建立连接后发送 同时通过拥塞控制 可靠传输 超时重传等措施保证了消息的可靠传输 按需传输 和 不重不漏

UDP是面向数据的传输 是按最大努力交互的传输 不保证数据能到达目标端

TCP是点对点的连接 和数据传输

UDP支持一对一 一对多 多对多

TCP封装了可靠传输等措施 所以它的协议头会比较长 因此传输的时候 相对会比较重量级 传输的整体效率比较慢

UDP没有这些功能的封装 比较简洁 所以它传输的时候 比较轻量级 传输的整体效率也比较快

在网络拥堵的时候 TCP会受此波及 主动放缓发送效率 这是因为TCP的拥塞控制特性

但是UDP由于在发送出去之后 完全不会管发送的结果 不用管当前的网络状况 所以可以说 UDP的发送速率不受网络堵塞的影响

TCP发送的时候 是以数据流的形式发送的

UDP则是以单个数据包的形式发送的

如何理解这里的所谓数据流呢?

TCP保持可靠传输是通过一个滑动窗口实现的 TCP中的所有数据报文都是通过这个滑动窗口来组织的

通过这个滑动窗口实现了按序到达 重发等效果

但是UDP没有这么一个原生的角色将数据包都组织起来

所以我们一般就说是TCP是按数据流 而UDP则是孤立数据包

TCP为什么可靠传输

首先 按序到达

TCP会为发出去的每一个数据包都设置一个序列号 并且按照这个序列号进行排序

观察该窗口中所有数据包是否顺序到达

超时重发

在TCP的场景下 当接收者接收到了对应序号的数据包 会返回一个ACK给发送者 表明数据包已经收到了

如果在规定时间捏没有收到这个ACK 则发送端会重发对应序号的数据包

连接管理

TCP是面对连接的协议,在发送数据前,TCP会通过三次握手四次挥手与目标建立连接。某种程度上确认连接的稳定性和鲁棒性

流量控制

这个是指当TCP连接的目标消费速率小于发送速率。此时滑动窗口内会积压数据包,为了保证数据包不会溢出,导致数据丢失。TCP会降低发送方的发送效率。

拥塞控制

这个是指在当前的网络拥塞,延迟比较大的时候或是检测到丢包的时候。TCP自己会执行的一些举措,包括 慢开始,拥塞避免,快重传,快恢复。

  • 慢启动 由慢速率开始发送 一步步提升发送的速度

  • 拥塞避免 到达界限速度之后 减慢发送增长速度( 发送增长速度(a下降) 发送速度仍处于上升(v上升) )

  • 拥塞发生 大幅度减小发送速度

  • 快恢复 以更快的加速度恢复发送速度 直至一个合适的值

LRU优化 参考Mysql

测开参与哪一些流程

开发一个产品的时候 首先需要理解产品的需求 才能根据这个需求来指定测试用例

然后构建测试环境 根据不同情况下的实现 编写测试用例 在这一过程中 如果现有的工具不能很好的测试需求的性能的话,可以自己去写一个测试工具来进行测试

然后就是在不同方面对功能需求进行测试

在这个过程中记录产品出现的bug 并且与团队中的其他角色进行合作修复

最后在产品验收之后 在其上线之后持续监控系统的表现

功能测试如何设计用例

如何涉及测试用例可以从在使用产品时候的各个角度来进行分析,这里结合大模型回答的情景简要说一下。

正常使用场景下,我们需要模拟用户的正常请求行为。例如说正常向大模型进行提问或者上传图片or上传文件等等。在这个环节同样需要测试上传多个文件图片 上传不同类型的文件和图片这样

边界值情境下 我们需要测试一下例如空值 最大值 最小值之类的边界值 来进行提问。在大模型提问场景下 我们可以尝试上传一些空文件 超大文件 上传多个文件(测试可同时上传的文件图片上限)或者是询问的时候 观察响应是否符合max_token之类的设置 以空值的形式调用访问接口 上传违禁词 违禁图片或文件的形式进行测试等等

我们还需要对安全情景进行测试 这一情景下 我们需要编写一些攻击程序的案例 例如说是SQL注入 XSS攻击等 并且看程序是否能正常应对并且反馈

对于特殊场景 这里的概括的话会比较笼统 具体可以体现在同一个账户是否能在同一时刻在两个端同时发起请求 统一账户是否能在短时间内发起多个请求 是否允许账户多端登录 并测试是否满足设置的上限 同时还有程序再进行请求的过程中 人为中断响应 此时程序和(页面)是否能正常的应对 或是在请求的时候 服务器异常 或者网络中断的情形下 是否能正常应对

特殊场景下 还有一些测试前端页面是否友好 是否兼容多个浏览器 多种客户端的情景 或者是快捷键是否生效等等

还有一类的话可以归类如性能测试 本质上就是极多用户同时进行访问 程序负载很大 的时候的响应以及程序对应的兜底措施 并且可以得到程序最大可容忍负载的一个极限值 根据这个极限值可以更好的继续监控 资源调控 开发也可以针对这个得到目前系统的性能瓶颈在哪 根据这个瓶颈更好的来进行性能调优

还有一些类似冒烟测试和回归测试 也就是我们需要验证程序在开发出新功能之后 已有的旧功能 核心功能是否受其影响 是否能正常运行 并且根据这个测试情景设置对应的测试用例

自动化测试指的是

自动化测试指的是编写一些测试脚本 模拟用户和程序的之间的交互 通过这个脚本来进行自动对程序某些方面进行测试

一般可以应用在回归测试 性能测试 API测试等等场景下

bug如何输出给开发 文档里写啥

通过优先级和重要程度进行归类

需要提供:

操作环境

复现步骤

bug结果

预期结果

截图:

日志:

影响模块:

紧急程度(优先级和严重程度)

版本号:

额外的备注:

当出现一个bug的时候 我们需要在文档上标注它的出现的环境 即当时的硬件环境 程序的版本号 出现bug的操作步骤 出现bug的操作结果 预期的操作结果 问题日志 bug的严重性和优先级

如何评判当前bug的优先级

从bug的影响范围 出现频率 bug的可修复难度 修复时间 牵扯模块 系统稳定性(是否会影响到系统的正常运行) 业务紧急度(是否影响到程序的核心功能运行)

以购物车 输入框 抢红包 大模型问答分别举例子

缓存击穿

缓存击穿指的是当某个热点Key失效的时候 大量的查询直接透过缓存打到DB上

这个问题的方案问题在于怎么让热点Ke变得不再这么热。

一个可性的方法是进行分片 将一个热点key分成多个 分片 然后将查询通过哈希等方式均匀的打到每一个分片上面

本地缓存热Key副本 将其存储在本地缓存当当中

但是这两个方法都需要维护缓存之间的一致性 或者redis缓存和本地缓存之间的一致性

还有一个方法是从业务上再度解耦Key 将热点的数据再度解耦分割 减小单个Key中包含的关键信息 从这个角度上 减小热Key

性能测试的时候 需要关注的参数

这个问题可以从多个方面上进行考虑

首先是在硬件上 程序执行的时候 服务器的硬件和软件的资源利用率之类的数据改变(内存 CPU等数据的改变) 以及在压测的时候 关注这几个层面上程序达到最大负载的时候的硬件数据

这个是一个方面

还有一些是程序在正常QPS下单个请求的执行时间 以及程序在QPS提升的时候 会对程序请求响应参数所造成的损耗 以及在压测的时候 程序可最大负载的请求数量 单个请求的耗费时间和延迟大小 此时的限流率等数值

还有可以涉及到程序具体代码的细节 例如说程序的某一块业务的CAS或者是自旋锁的性能表现如何 是否打到预期 与直接使用悲观锁的性能和成本的性价比之类的数据

除此之外还可以从中间件的思路上进行思考

例如说是最老生常谈的MySQL和Redis存储层的这两者 可以表现为单位时间打到DB和Redis的数据分别有多少 也就是所谓的缓存命中率 与单纯使用DB和加上cache之后的提升率 还有缓存击穿的频率之类的

然后还有MQ 可以体现在单位时间内的生产者任务生产数量和单位时间内消费者任务消费数量和在MQ中的消息挤压数量 可以通过着一些得知两模块之间的运行效率的区别 并且来进行人为调控之类的

对于Nginx和域名这些 还可以测试Nginx下 反向代理和负载均衡的额外耗时 也就是Nginx对直接访问所带来的额外代价和 在执行负载均衡的时候 每个服务器平均的请求率 和到达的请求数量 判断当前的负载均衡算法是否合理 是否需要更换别的算法等等 在DNS这个层面上 我们还可以测试DNS解析域名所带来的额外耗时

性能差如何处理 网络io 资源 sql 代码

首先要通过单元测试 得知当前的性能瓶颈是在哪一块 缩小调优的范围

对于网络io 在请求频繁但是性能差的目标地点 部署新服务器集群 可以在协议上进行优化(QUIC + UDP) 数据轻量级序列化PB

资源的话 一般来说由硬件和中间件的性能决定的 这种情况下可以提高硬件的性能 或者根据具体场景高度定制中间件 使其更好的服务于业务

sql的话,一般来说是mysql当前的连接数太多了 或者是索引没有设计好 或者sql没写好 mysql选错了索引 等原因 对于这些原因可以酌情kill掉空闲连接 减小max_connetions的值 减小分配到他的空间等方法 对于索引没有设计好的话 在运行时可以利用主从切换动态创建更新索引 等等方法 利用插件重写query语句等等方法 选错索引则也是使用重写脚本来进行一个force index的操作

Linux有用过吗 常用的命令

Linux在学习docker mq等中间件和操作系统的时候经常接触 一般来说是通过云服务器 WSL 或者是虚拟机使用的。我现在使用它结合Nginx来部署了我自己的个人博客网站。然后在学习mit6.s081运行xv6的时候 也是基于WSL的操作环境学习的

常用的命令包括 cd pwd mkdir rmdir mv cp cat top df free htop lsof tar echo grep find wc netstat ls touch head tail more less vim nano xargs trace

三次握手四次挥手

三次握手四次挥手指的是服务器和客户端在建立TCP连接和断开TCP的时候所需要做的准备

三次握手

  1. 客户端发起连接请求 向服务器发起建立连接请求
  2. 服务器收到请求 响应一个ACK
  3. 客户端收到服务器发起的请求 再度返回一个ACK 连接成功建立

四次挥手

  1. 客户端发起一个断开连接的请求
  2. 服务器收到这个 返回ACK 继续当前仍未结束的数据发送
  3. 客户端收到ACK
  4. 服务器当前所有数据发送完毕 再度发送ACK 客户端在收到后返回一个ACK

补充:

三次握手的途中:在客户端想要建立连接的时候 发送请求的时候 是处于SYN_SEND状态 而服务器收到之后 处于SYN_RECEIVER状态

然后服务器返回ACK之后 客户端处于ESTABLISHED 然后返回ACK给服务器 服务器更新为ESTALISHED

四次挥手的途中:客户端发送断开连接请求时 此时处于FIN_WAIT1状态 等待服务器剩下的数据传输

服务器收到了之后 返回ACK并更新状态为CLOSE_WAIT

然后服务器在将剩余数据发送完之后 再次更新状态为LAST_ACK 发送最后一次ACK给客户端

客户端收到之后 更新状态为TIME_WAIT然后发ACK给服务器 服务器更新状态为CLOSED

过了一段时间之后 客户端会再次更新自己的状态为CLOSED

这个一段时间是多少?

是2MSL MSL是网络中报文传输的时间单位

等待2MSL的时间本质上是防止网络传输中还有某些报文因为连接断开而丢失

JMM

JMM是java的内存模型

首先每个线程都有自己的一个操作空间 与本地缓存 即ThreadLocal

然后单进程内的多个线程共享进程内的资源 如内存空间 变量 数据值等 这些共享的数据是存储在堆当中的

假如某个线程想读取堆中的数据 他会先CPU高速缓存下查找有没有对应的值 如果由即返回 没有则到堆中获取值并且返回

而这个缓存是有可能与堆中的最新值不一致的 所以读取数据的时候 有可能会读取不到最新之 即损坏了可见性

这时候可以使用volatile变量的方法 禁用CPU在这场景下的高级缓存 然后保证每一次读取值的时候 都去堆中获取

这样只是保证了可见性 但是并没有保证操作的原子性 还是有可能会出现竞态问题 这时候就需要使用类似锁和并发类进行开发了

算法

141. 环形链表 同向双指针遍历

19. 删除链表的倒数第 N 个结点 同向双指针

21. 合并两个有序链表 同向双指针

88. 合并两个有序数组 同向双指针

102. 二叉树的层序遍历 BFS板子

53. 最大子数组和 动态规划

94. 二叉树的中序遍历 二叉树遍历顺序 递归和非递归(栈) 先序:中左右 中序 左1中右 后续:左右中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> ret = new ArrayList<>();
Stack<TreeNode> st = new Stack<>();
while(root != null || !st.isEmpty()){
while(root != null){
st.push(root);
root = root.left;
}
root = st.pop();
ret.add(root.val);
root = root.right;
}
return ret;
}
}