1.冯诺依曼计算机体系特点?与程序有关?
五大特点
- 存储程序:程序和数据存放在存储器中,计算机自动取指令执行(核心,和程序强相关)
- 指令和数据同等存放在内存;指令由操作码+地址码组成
- 二进制表示数据、指令
- 五大硬件组件:运算器、控制器、存储器、输入设备、输出设备
- 指令顺序执行,可跳转改变执行顺序
核心就是存储程序思想:把程序预先存内存,CPU自动读取执行,这是冯诺依曼最核心和程序相关的点。
2.电子计算机三器两部组成,三器两部是什么?
三器两部 三器:运算器、控制器、存储器 两部件:输入设备、输出设备 就是冯诺依曼五大硬件。
3.ARM架构和X86架构怎么区分的?
| X86 | ARM | |
|---|---|---|
| 指令集 | CISC复杂指令集 | RISC精简指令集 |
| 授权模式 | 芯片厂商自研设计 | 架构授权,各家可以改内核 |
| 功耗 | 功耗高,性能强 | 低功耗,省电 |
| 代表设备 | Intel/AMD PC、服务器 | 手机、树莓派、苹果M系列、嵌入式 |
| 软件兼容性 | 程序需要分别编译,二进制不互通 | 同一程序需要分别编译x86版本、arm版本 |
区分关键点:
- X86:复杂指令,高性能高功耗;ARM:精简指令,低功耗。 现在服务器也有ARM服务器;docker镜像要区分
amd64(x86_64)、arm64。
4.设计CPU中经典指令集和复杂指令集?
- CISC复杂指令集(X86):指令多,指令长度不固定,一条指令做复杂操作;硬件电路复杂。
- RISC精简指令集(ARM、MIPS):指令数量少,指令定长,只做简单操作;复杂任务靠多条指令组合,硬件简单,流水线容易做。
注意:RISC是精简,CISC复杂。
5.ISO OSI七层模型 和 TCP/IP五层模型
OSI七层(从上到下)
7.应用层 6.表示层 5.会话层 4.传输层 3.网络层 2.数据链路层 1.物理层
TCP/IP五层(实际互联网在用)
5.应用层(HTTP、FTP、DNS) 4.传输层(TCP/UDP) 3.网络层(IP、ICMP) 2.数据链路层(MAC) 1.物理层(网线、电信号)
面试常考:ping属于网络层ICMP;HTTP应用层;TCP传输层。
6.电脑本地MySQL,Nginx反向代理能不能做?
✅可以做。Nginx本身不解析mysql协议 ,不能用普通proxy_pass http://;要用 stream模块(四层TCP反向代理)
-
nginx.conf外层写stream块,监听端口,转发到mysql的127.0.0.1:3306
stream {
server {
listen 3307;
proxy_pass 127.0.0.1:3306;
}
}
注意:编译nginx需要带
--with-stream模块,http块不能代理mysql。
7.能ping通,页面访问不通排查思路
ping通代表网络层通,上层传输层/应用层故障,分步排查
- telnet/nc测试端口通不通:
telnet ip 80看端口是否开放 - 防火墙:服务器防火墙、云服务器安全组是否放行端口
- 服务是否启动:nginx/tomcat是否正常监听对应端口
- 监听地址问题:服务只监听127.0.0.1,没有监听0.0.0.0,外部无法访问
- Nginx配置错误、后端服务报错、DNS解析错误
- 路由、iptables策略拦截
8.Chariot有没有使用过?
应为 chariot net(Chariot),网络性能测试工具,测吞吐量、时延。很多后端开发没实操;可以回答:了解概念,没有生产实操;平时用curl、ab、wrk做压测。
9.Linux没有浏览器命令行看网页
两个工具:curl / wget
10.curl命令
curl:命令行http客户端
curl https://www.baidu.com #打印页面源码
curl -I https://www.baidu.com #只看响应头
curl -X POST -d "k=v" url #post请求
curl -v url #打印完整请求交互过程,排错神器
用途:测试接口、看返回、调试http、模拟请求。
11.VI和VIM区别
- vi:Linux系统自带原始编辑器,功能简陋
- vim:vi的增强版本,vi improved;语法高亮、代码着色、缩进、多撤销、插件 。 命令vi很多系统实际软链接到vim;最小化安装系统只有vi没有vim。
12.Linux管道命令 |
管道 |:把前一个命令标准输出stdout,作为后一个命令标准输入stdin 示例:
ps -ef | grep java
cat xxx.log | grep error
ls -l | more
注意:管道传递的是输出文本,不是命令参数。xargs是把输出转为命令参数。
13.阿里MySQL规范单表最多多少列
建议不超过30列。 原因:行数据过大,IO变差;InnoDB一页16k,列太多单行占用大,每页存行数变少,缓冲池效率下降。
14.MVCC
多版本并发控制 Multi‑Version Concurrency Control InnoDB实现隔离级别核心机制,不加锁实现读,快照读。
- 核心:undo log回滚日志生成历史版本;read view读视图判断版本可见性。
- 当前读:select ... for update / update delete,加锁读取最新版本
- 快照读:普通select,读取快照版本,不加锁。
15.Mysql默认隔离级别?可不可以改?
- MySQL InnoDB 默认:REPEATABLE‑READ 可重复读
- ✅可以改 全局:
set global transaction_isolation='READ‑COMMITTED';会话:set session transaction_isolation='READ‑COMMITTED';也可以my.cnf配置文件永久修改。
Oracle默认是读已提交READ‑COMMITTED。
16.可重复读在程序里有什么影响?
同一个事务内,多次普通select读取到同一个快照版本 ,哪怕其他事务已经提交修改数据,本事务看不到别人提交的新数据。 优点:避免不可重复读; 缺点:快照读看不到其他事务已提交最新数据,会出现幻觉,库存、状态判断容易踩坑。
17.可重复读读不到最新库存,怎么办?
场景:事务中快照读拿到旧库存,别人已经扣减库存,自己读到旧值,业务出错。 读到最新数据方案:
- 使用当前读 :
select xxx from stock where id=? for update;加行锁,读取最新已提交数据;(扣库存主流方案,悲观锁) - 降低隔离级别改为读已提交RC,快照读就可以看到其他事务提交的数据;
- 乐观锁版本号机制,update带version条件; ❌不要事务中途commit再查询,会破坏事务。
18.Mysql事务传播机制?
事务传播是Spring的@Transactional,不是mysql数据库层面。 7种传播行为:
- REQUIRED(默认):有事务加入,没有新建
- SUPPORTS:有就用,没有就非事务运行
- MANDATORY:必须已有事务,否则抛异常
- REQUIRES_NEW:新建独立事务,挂起旧事务
- NOT_SUPPORTED:挂起事务,非事务执行
- NEVER:不能有事务,有则报错
- NESTED:嵌套事务,保存点savepoint
19.this调用@Transactional事务还有效吗?为啥?如何解决?
无效,事务不生效 原因:Spring AOP事务基于动态代理;this.方法()调用是对象内部直接调用方法,不走代理对象,不会执行事务增强逻辑。
解决:
- 注入自己
@Autowired private XXXService self; self.xxx(); - 通过AopContext获取代理对象 ((XXXService)AopContext.currentProxy()).method(); 需要开启expose‑proxy=true
- 把事务方法拆分到另一个Service。
20.深分页?解决方法?延迟关联与主键索引优化
问题:select * from t limit 100000, 10,mysql扫描100010行,丢弃前10万,返回10条,性能极差。
方案1:延迟关联(子查询主键)
先查主键,再关联拿完整行
select t.* from t inner join (select id from t limit 100000,10) tmp on t.id = tmp.id;
利用主键索引覆盖,回表次数少。
方案2:主键书签(业务推荐)
不用offset,记录上一页最大id,where id > #{lastId} limit 10,避免扫描大量历史数据;适合有序自增主键,不能跳页。
其他:ES分页;业务限制不允许跳很深页码。
offset大本质:需要扫描并抛弃前面大量数据。
21.Mybatis‑Plus saveBatch源码怎么实现
MP默认saveBatch(Collection)不是真正批量 源码:循环遍历实体,循环执行 insert(),每一条执行一次insert语句,默认还是多条sql;jdbc批处理没开启。 底层就是for循环调用insert,只是封装循环。
真正批量入库:
- jdbc连接串加上
rewriteBatchedStatements=true - 使用
SqlSession batch批量模式;或者MP的saveBatch第二个参数设置批次大小。
坑:很多人误以为saveBatch是数据库批量insert values(),(),();默认不是。
22.PreparedStatement 和 Statement,除防SQL注入外预处理功能
- 预编译sql模板,数据库端缓存执行计划,多次执行同模板sql可以复用执行计划,减少编译开销;循环批量插入性能提升
- 参数设置,自动处理类型转换,不用手动拼接字符串引号、日期
- 二进制传输参数,不用拼接字符串,特殊字符自动转义
Statement每次执行都编译sql,无法缓存计划。
23.批量入库1000条,其中一条字符越界,全部回滚怎么办
场景:一批1000条,单条报错,整个批次全部回滚,想要部分成功部分失败。
- 数据库层面,一批batch是同一个事务,一条异常全部回滚,数据库不支持"部分成功" 方案:
- 拆分批次:大1000拆小批次,每200条一个批次;一个批次失败只回滚这一小批
- 捕获异常,失败批次再做单条重试,识别坏数据;
- 业务校验前置,入库前校验字段长度,拦截非法数据;
- 分治:批量先落临时表,再做校验过滤,再写入业务表。
MySQL JDBC批处理,如果没有开启rewriteBatchedStatements,本质还是逐条发送,报错同样会事务回滚。
24.Docker装Mysql持久化,宿主机保存数据
两种方式持久化:
-
bind mount 挂载宿主机目录(常用)
-v /宿主机本地路径:/var/lib/mysql
/var/lib/mysql是mysql容器内部数据目录,映射宿主机,容器删除数据还在宿主机。
- docker volume 命名卷,docker管理存储。
注意宿主机目录权限,容易出现权限报错。
25.Docker看日志命令
docker logs 容器ID/容器名
docker logs -f 容器名 #实时跟踪日志
docker logs --tail 200 容器名 #看末尾200行
26.Docker mysql 3306端口被占用
- 先看谁占用宿主机3306端口:
netstat -tulpn | grep 3306/ss -tulpn - 方案A:不使用宿主机3306,映射别的端口
-p 3307:3306;宿主机3307映射容器内部3306 - 方案B:停止占用3306的本地mysql服务,再启动docker mysql映射3306。
-p 宿主机端口:容器端口,容器内部mysql永远3306,改前面宿主机端口。
27.自己打Docker镜像
两种方式:
-
Dockerfile构建(标准) 写Dockerfile,定义基础镜像、复制文件、运行命令、暴露端口、启动命令;
FROM openjdk:17
COPY app.jar /app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
构建:docker build -t myapp:v1 .
- 不推荐:
docker commit,基于运行容器打包镜像,镜像臃肿,不可复现。
企业全部使用Dockerfile。
28.k8s接触过吗?
面试简短版回答: 了解k8s核心概念Pod、Deployment、Service、ConfigMap、Namespace; Pod最小调度单元;Deployment管理pod副本、滚动更新;Service做服务发现负载均衡; 自己做过简单yaml部署应用;没有深度生产运维,懂核心资源对象。
如果完全没接触就如实:了解概念,知道组件,没有实操部署。
29.node.js
- 基于V8引擎的JS运行时;可以后端写服务,非阻塞IO事件驱动,适合IO密集场景,不适合CPU密集计算。
- npm包管理器;express、koa web框架。 Java后端面试,知道:JS后端运行环境、事件循环、异步非阻塞即可。