无法跳转到题目请在右侧目录索引中输入对应题目的序号点击即可
Java 的三大特性是:
-
封装(Encapsulation) 👉 把数据和操作封装到类中,对外只暴露必要接口,隐藏内部实现。 👉 比如用
private修饰属性,提供get/set方法。 -
继承(Inheritance) 👉 子类自动拥有父类的属性和方法,提高代码复用性。 👉 Java 是单继承,多实现(类只能继承一个类,但可以实现多个接口)。
-
多态(Polymorphism) 👉 同一个方法在不同对象上表现不同的行为。 👉 常见形式有方法重载(编译时)和方法重写(运行时)。
一句话总结:
封装保证安全,继承提高复用,多态提升灵活性,是面向对象的三大核心。
Java 一共有 8 种基本数据类型:
| 类型 | 占用空间 | 默认值 | 描述 |
|---|---|---|---|
| byte | 1 字节 | 0 | 整型,范围 -128 ~ 127 |
| short | 2 字节 | 0 | 整型 |
| int | 4 字节 | 0 | 默认整型 |
| long | 8 字节 | 0L | 大整数 |
| float | 4 字节 | 0.0f | 单精度小数 |
| double | 8 字节 | 0.0d | 双精度小数,默认浮点型 |
| char | 2 字节 | '\u0000' | 单个字符 |
| boolean | ~1 字节* | false | 只有 true/false |
注:boolean 在 JVM 中并没有明确规定大小,一般按一个字节处理。
一句话记忆法:
“4整(byte、short、int、long),2浮(float、double),1字(char),1布(boolean)”
Spring Boot 最重要的注解是:
** @SpringBootApplication**
它是 Spring Boot 的入口注解,相当于三个注解的组合:
@SpringBootApplication =
@SpringBootConfiguration +
@EnableAutoConfiguration +
@ComponentScan📌作用总结一句话:
“它表示这是一个 Spring Boot 应用的入口,能开启自动配置和组件扫描。”
其他常用注解(按功能分类):
- 组件类注解(用于创建 Bean):
@Component:通用组件@Service:业务逻辑层@Repository:持久层(自动处理异常转换)@Controller/@RestController:控制层(前端接口)
- 依赖注入:
@Autowired:自动注入 Bean(按类型)@Value:注入配置值(如 application.yml)
- 配置和自动化相关:
@Configuration:定义配置类@Bean:在配置类中手动注册 Bean@EnableAutoConfiguration:开启自动配置(Spring Boot 核心)@ConditionalOnXXX:条件装配(Spring Boot 特有)
- Web 开发相关:
@RequestMapping/@GetMapping/@PostMapping:映射 HTTP 请求@RequestParam/@PathVariable/@RequestBody:绑定请求参数
- 其他常见注解:
@Slf4j:自动引入日志对象(Lombok)@Transactional:声明式事务管理@Entity、@Table、@Id:JPA 注解(用于 ORM)
一句话总结:
“Spring Boot 最核心的是
@SpringBootApplication,其他常用注解分为组件、注入、配置、Web 等几类,配合自动装配机制,极大简化了开发流程。”
MySQL 主从复制是怎么实现的?
MySQL 主从复制本质是**基于二进制日志(binlog)**的异步复制机制,主要步骤:
-
主库(Master)写操作产生 binlog 所有对数据库的写操作(insert、update、delete)都会记录到主库的二进制日志中。
-
从库(Slave)通过 IO 线程读取主库 binlog 从库启动一个 IO 线程,连接主库,实时拉取 binlog 并保存到本地的中继日志(relay log)中。
-
从库 SQL 线程执行中继日志 从库启动 SQL 线程,读取中继日志内容,执行写操作,实现数据同步。
-
复制过程异步进行 主库不等待从库完成复制,写操作性能影响小,但可能有短暂延迟。
一句话总结:
MySQL 主从复制通过主库写二进制日志,从库拉取并执行日志,保持数据同步,是异步复制机制。
补充点:
- 复制模式:异步、半同步、组复制等,主流是异步复制;
- 复制延迟:从库滞后于主库,可能导致读数据不一致;
- 主从切换:备份与容灾方案关键。
MySQL 的隔离级别有哪些?
MySQL 支持四个标准的隔离级别:
- 读未提交(Read Uncommitted) — 会发生脏读、不可重复读和幻读;
- 读已提交(Read Committed) — 解决脏读,但仍可能出现不可重复读和幻读;
- 可重复读(Repeatable Read) — 解决脏读和不可重复读,MySQL 默认级别;
- 可串行化(Serializable) — 最高级别,防止所有并发问题,包括幻读。
幻读怎么解决?
-
MySQL 在默认的 Repeatable Read 级别下,通过 间隙锁(Gap Lock) 和 临键锁(Next-Key Lock) 实现对范围的锁定,防止其他事务在范围内插入新行,从而避免幻读问题。
-
所以,MySQL 的 Repeatable Read 实际上解决了幻读,这和标准 SQL 理论有一点不同。
一句话总结:
MySQL 默认的 Repeatable Read 隔离级别通过间隙锁机制避免了幻读。
MySQL 四大事务特性(ACID):
-
原子性(Atomicity) 事务中的操作要么全部完成,要么全部不做,不会停留在中间状态。
-
一致性(Consistency) 事务执行前后,数据库都保持合法状态,数据规则不被破坏。
-
隔离性(Isolation) 多个事务并发执行时,互不干扰,仿佛是串行执行。
-
持久性(Durability) 一旦事务提交,结果永久保存,即使系统崩溃也不会丢失。
原子性是怎么实现的?
- MySQL 通过**日志机制(Undo Log + Redo Log)**保证原子性。
- Undo Log 用于事务回滚,能撤销未完成的修改,保证“全做或全不做”。
- 事务提交时,Redo Log 确认写入磁盘,保证修改持久。
持久性是怎么实现的?
- 通过 Redo Log(重做日志) 实现。
- 数据修改先写入Redo Log,并刷盘,确保即使数据库崩溃,也能通过重做日志恢复数据。
- 另外,MySQL 还定期将内存中的数据页刷新到磁盘(刷脏页),保证数据持久。
一句话总结:
原子性靠 Undo Log 支持回滚,持久性靠 Redo Log 保证数据即使崩溃也能恢复。
服务端渲染(SSR)和客户端渲染(CSR)的区别:
| 特点 | 服务端渲染(SSR) | 客户端渲染(CSR) |
|---|---|---|
| 页面生成位置 | 服务器生成完整 HTML 页面 | 浏览器用 JavaScript 渲染页面 |
| 首屏加载速度 | 快,页面直接返回完整内容 | 慢,先加载空白页面再执行 JS 渲染 |
| SEO 友好度 | 好,搜索引擎能直接抓取内容 | 差,需额外配置 SSR 或预渲染 |
| 交互响应性 | 依赖服务器,用户操作需更多请求 | 快,交互大多在客户端完成 |
| 开发复杂度 | 相对复杂,需服务器支持 | 简单,纯前端开发 |
一句话总结:
服务端渲染页面由服务器生成,首屏快且 SEO 好;客户端渲染页面由浏览器生成,交互更流畅但首屏较慢。
网页完整的渲染过程:
-
浏览器发送请求 浏览器向服务器发送 HTTP 请求,获取网页资源(HTML、CSS、JS 等)。
-
服务器响应 服务器返回 HTML 文档。
-
HTML 解析生成 DOM 树 浏览器开始解析 HTML,生成 DOM(文档对象模型)树。
-
CSS 解析生成 CSSOM 树 浏览器解析 CSS 文件和内联样式,生成 CSSOM(CSS 对象模型)树。
-
构建渲染树(Render Tree) 浏览器将 DOM 树和 CSSOM 树结合,生成渲染树,只包含需要显示的节点。
-
布局(Layout 或 Reflow) 浏览器计算渲染树中每个节点的几何信息(大小、位置)。
-
绘制(Paint) 浏览器将布局信息转换成屏幕上的像素,绘制到屏幕。
-
执行 JavaScript 浏览器解析并执行 JS 脚本,可能会修改 DOM 或 CSSOM,触发重绘或回流。
一句话总结:
浏览器请求资源,解析 HTML 和 CSS 生成渲染树,计算布局并绘制页面,同时执行 JavaScript 动态修改页面。
进程和线程的区别:
| 特点 | 进程(Process) | 线程(Thread) |
|---|---|---|
| 定义 | 操作系统资源分配的基本单位 | CPU 调度的基本单位 |
| 资源拥有 | 拥有独立的内存空间和系统资源 | 共享所属进程的内存和资源 |
| 创建销毁 | 创建销毁开销较大 | 创建销毁开销较小 |
| 通信方式 | 进程间通信(IPC)较复杂 | 线程间通信直接访问共享内存 |
| 调度 | 由操作系统调度 | 由进程内的调度器管理 |
| 稳定性 | 一个进程崩溃不影响其他进程 | 一个线程异常可能影响整个进程 |
一句话总结:
进程是资源分配的独立单位,线程是执行调度的最小单位,线程共享进程资源,通信更高效。
进程间通信的常见方式:
-
管道(Pipe)
- 只能在有亲缘关系的进程间通信(如父子进程)。
- 数据以字节流形式单向传输。
-
命名管道(Named Pipe / FIFO)
- 支持无亲缘关系进程间通信。
- 通过名字访问,依然是字节流。
-
消息队列(Message Queue)
- 以消息为单位传递,支持异步通信。
- 操作系统维护队列,进程读写消息。
-
共享内存(Shared Memory)
- 不同进程共享一块内存区域,速度最快。
- 需要同步机制(如信号量)保证数据一致。
-
信号量(Semaphore)
- 主要用于进程同步,控制访问共享资源的数量。
- 常与共享内存结合使用。
-
套接字(Socket)
- 适用于网络通信,也可用于本地进程通信。
- 支持跨机器通信。
一句话总结:
进程间通信方式多样,管道和消息队列适合简单传输,共享内存速度快但需同步,套接字适合网络通信。
线程间通信的方式
- 单服务(同一进程内多线程)
-
共享内存 线程共享进程的内存空间,直接读写共享变量是最常见的通信方式。
-
同步机制 为避免竞态条件,常用锁机制保证线程安全,比如:
synchronized(Java)Lock接口(如 ReentrantLock)- 信号量(Semaphore)
- 监视器(wait/notify)
-
线程间消息队列 如 Java 中的
BlockingQueue,线程通过队列安全传递数据。
- 多服务(跨进程或分布式服务间通信)
-
网络通信
- HTTP/REST API
- RPC(如 gRPC、Thrift)
- WebSocket
-
消息中间件
- Kafka、RabbitMQ、ActiveMQ 等消息队列
- 用于异步解耦和流量削峰
-
共享存储
- Redis、数据库等作为通信介质
一句话总结:
同一进程内线程通信靠共享内存和同步机制,多服务间通信靠网络协议和消息中间件。
Linux 常用命令(重点是搜索相关)
| 命令 | 作用 | 简要说明 |
|---|---|---|
ls |
列出目录内容 | ls -l 查看详细信息 |
cd |
切换目录 | cd .. 返回上级目录 |
pwd |
显示当前路径 | |
cp |
复制文件或目录 | |
mv |
移动或重命名文件 | |
rm |
删除文件或目录 | rm -r 删除目录及内容 |
cat |
查看文件内容 | |
more/less |
分页查看文件 | less 支持上下翻页 |
grep |
文件内容搜索 | grep "关键词" 文件名 |
find |
查找文件 | find /path -name "file.txt" |
locate |
快速查找文件 | 依赖数据库,先更新 updatedb |
ps |
查看进程 | ps aux 查看所有进程 |
top |
实时查看系统资源 | |
chmod |
修改文件权限 | |
chown |
修改文件所有者 | |
tar |
打包/解包 | tar -zxvf 解压 tar.gz 文件 |
搜索相关重点命令:
grep:按内容搜索,常用配合管道符,例如ps aux | grep java查找 java 进程find:按文件名查找,支持复杂条件,如时间、大小等locate:速度快,基于索引数据库,但不适合实时文件变化
一句话总结:
Linux 搜索文件用 find 和 locate,搜索内容用 grep,结合管道能高效定位。
Linux 通讯常用命令:
| 命令 | 作用 | 简要说明 |
|---|---|---|
ping |
测试网络连通性 | 通过 ICMP 协议检测目标是否可达 |
traceroute |
跟踪路由路径 | 显示数据包经过的路由节点 |
netstat |
显示网络连接状态 | 查看端口、连接、路由等 |
ss |
替代 netstat,显示套接字 | 显示 TCP、UDP 连接 |
ifconfig / ip |
配置或查看网络接口 | ip 是新命令,功能更强大 |
telnet |
测试端口连通性 | 连接到远程端口,调试服务 |
nc (netcat) |
读写网络连接,端口监听 | 简易的 TCP/UDP 客户端和服务器 |
curl |
网络请求工具 | 测试 HTTP、FTP 等协议 |
wget |
命令行下载工具 | 支持 HTTP、FTP |
Linux 通讯原理简述:
-
基于 TCP/IP 协议栈 Linux 网络通信遵循 TCP/IP 协议族,主要负责数据的传输和路由。
-
套接字(Socket)通信机制 网络通信核心是套接字,应用程序通过套接字接口进行数据发送和接收。
-
数据包在内核中传递 应用层的数据经过传输层(TCP/UDP)、网络层(IP)、链路层处理,封装成数据包发送。
-
网络设备驱动负责物理传输 包括以太网卡、无线网卡等硬件,完成实际的信号传输。
一句话总结:
Linux 网络通信依赖 TCP/IP 协议和套接字机制,常用命令如 ping、netstat 和 nc 用于测试和调试网络连接。
TCP 三次握手是什么?
TCP 三次握手是建立一个可靠连接的过程,目的是双方确认彼此的发送和接收能力,确保连接可靠。
为什么必须要三次?
-
第一次握手(SYN):客户端发送 SYN 包(请求连接),告诉服务器客户端的初始序列号(Seq)。
-
第二次握手(SYN-ACK):服务器收到后,回复 SYN-ACK 包,确认客户端的序列号(Ack = Seq + 1),并发送自己的序列号。
-
第三次握手(ACK):客户端收到后,发送确认包 ACK,确认服务器的序列号(Ack = 服务器 Seq + 1)。
为什么不能少于三次?
-
第一次握手只确认客户端请求连接,服务器不知道客户端是否准备好接收数据。
-
第二次握手确认了客户端请求,并且告诉客户端服务器也准备好,但客户端还没确认服务器的状态。
-
第三次握手确保客户端和服务器双方都已确认对方的接收能力,连接正式建立。
一句话总结:
三次握手确保双方收发能力互相确认,保证连接建立时双方都准备好可靠通信。
HashMap 底层原理:
- 结构:基于数组 + 链表(JDK7)/数组 + 链表 + 红黑树(JDK8 及以后)实现。
- 存储:通过 key 的
hashCode()计算哈希值,定位数组索引。 - 冲突处理:哈希冲突时,链表存储相同索引的多个元素,元素多到一定阈值会转成红黑树,提升查找效率。
- 扩容机制:当负载因子超过 0.75 时,HashMap 会自动扩容,容量翻倍,并重新计算元素位置。
- 线程安全:HashMap 本身 非线程安全,多线程并发访问可能导致数据不一致或死循环。
线程安全的 Map 实现:
-
Hashtable
- 早期线程安全的实现,所有方法都加了
synchronized,性能较低。
- 早期线程安全的实现,所有方法都加了
-
Collections.synchronizedMap(Map<K,V>)
- 通过包装普通 Map,方法加同步,适合低并发场景。
-
ConcurrentHashMap
- 高性能线程安全实现,采用分段锁(JDK7)和 CAS + 锁结合(JDK8),支持高并发。
-
ConcurrentSkipListMap
- 线程安全的有序 Map,基于跳表实现,支持并发访问。
一句话总结:
HashMap 用数组加链表/红黑树存储元素,非线程安全;线程安全的有 Hashtable、同步包装的 Map 和高性能的 ConcurrentHashMap。
Spring Boot 启动注解是什么?
@SpringBootApplication 是启动注解,标记主程序入口。
它内部包含的三个主要注解:
-
@SpringBootConfiguration- 标明这是一个配置类,继承自
@Configuration,告诉 Spring 这是一个配置文件。
- 标明这是一个配置类,继承自
-
@EnableAutoConfiguration- 启用自动配置,根据类路径和配置自动装配相关的 Bean,减少手动配置。
-
@ComponentScan- 开启组件扫描,自动发现和注册
@Component、@Service、@Controller等 Bean。
- 开启组件扫描,自动发现和注册
补充说明
- 这三个注解组合起来,实现了 Spring Boot 应用的“约定优于配置”理念。
@SpringBootApplication让你只需要写一个注解就能完成配置和扫描。
一句话总结:
@SpringBootApplication 是启动注解,包含配置声明、自动配置和组件扫描三大功能,简化 Spring Boot 项目启动流程。
MySQL 事务是什么?
事务是一组要么全部执行成功、要么全部不执行的操作,保证数据的一致性和完整性。
事务的四大特性(ACID):
-
原子性(Atomicity) 事务中的操作是一个不可分割的整体,要么全部成功,要么全部失败。
-
一致性(Consistency) 事务执行前后,数据库的状态必须保持一致,不违反任何约束。
-
隔离性(Isolation) 并发执行的事务互不干扰,事务之间的操作彼此隔离。
-
持久性(Durability) 事务一旦提交,其结果是永久保存的,即使系统崩溃也不会丢失。
一句话总结:
MySQL 事务保证操作的原子性、一致性、隔离性和持久性,确保数据安全可靠。
- 支持 持久连接(Connection: keep-alive),减少建立连接开销
- 支持 管道化(Pipelining),但浏览器支持不完善
- 支持 分块传输编码,服务器可以边生成边发送响应
- 增加了更多的缓存控制和请求头字段
- 请求和响应头部较大,文本格式,效率较低
- 用于解决异步操作的回调地狱
- 状态不可变(pending → fulfilled/rejected)
- 支持链式调用
.then() - 提供错误捕获
.catch() - 可以并发处理多个异步操作(
Promise.all)
| 存储类型 | 存储位置 | 生命周期 | 大小限制 | 作用域 | 是否随请求发送给服务器 |
|---|---|---|---|---|---|
| localStorage | 浏览器 | 永久保存(除非手动清除) | 5-10MB | 同源 | 否 |
| sessionStorage | 浏览器 | 会话结束即清除 | 5MB | 同源,且窗口/标签独立 | 否 |
| cookie | 浏览器 | 可设置过期时间 | 4KB | 同源,且路径可细分 | 是,随请求发送服务器 |
- 通过迭代或递归将链表的
next指针反转 - 迭代思路:用三个指针
prev、curr、next依次改变链接方向 - 时间复杂度 O(n),空间复杂度 O(1)
useCallback(fn, deps):缓存函数实例,避免不必要的函数重创建useMemo(fn, deps):缓存函数的返回值,避免重复计算memo(Component):高阶组件,缓存组件输出,防止不必要的重新渲染
memo会浅比较前后 props- 如果 props 没变化,跳过渲染,复用上次结果
- 如果 props 变化,重新渲染组件
- 弹性盒模型(Flexbox)
- 动画和过渡(Animation & Transition)
- 媒体查询(Media Queries)
- 圆角(border-radius)
- 阴影(box-shadow & text-shadow)
- 渐变(linear-gradient、radial-gradient)
- 多列布局(multi-column)
- 容器设置
display: flex - 方向:
flex-direction(row, column) - 主轴对齐:
justify-content - 交叉轴对齐:
align-items - 子项可伸缩:
flex-grow,flex-shrink,flex-basis
let和const声明变量- 箭头函数
()=>{} - 模板字符串
`text ${var}` - 解构赋值
- 扩展运算符
... - Promise
- 模块化
import/export - 默认参数、剩余参数
- 类和继承
- Symbol 类型
- 遍历类:
forEach,map - 过滤类:
filter - 归约类:
reduce - 查找类:
find,findIndex - 判断类:
some,every - 排序:
sort - 添加/删除:
push,pop,shift,unshift,splice - 复制:
slice - 扁平化:
flat
- 高性能:基于 HTTP/2,支持多路复用、二进制传输,速度快、延迟低
- 强类型接口:用 Protocol Buffers 定义接口,自动生成代码,类型安全
- 多语言支持:支持多种编程语言,方便跨平台微服务通信
- 双向流:支持客户端、服务器流式数据传输,灵活高效
- 简单易用:接口定义明确,调用像本地函数一样简洁
- 写性能压力大,可能导致延迟增加
- 锁竞争加剧,特别是 InnoDB 表的行锁/表锁,可能引发阻塞
- 主库负载上升,写多会影响主从复制效率
- 磁盘 IO 增加,可能导致 IO 瓶颈
- 二进制日志变大,影响复制和恢复速度
- 主库将所有写操作记录到 二进制日志(binlog)
- 从库启动 IO 线程连接主库,拉取 binlog 并写入 中继日志(relay log)
- 从库启动 SQL 线程,执行中继日志,完成数据同步
- 这种复制是异步的,主库不等待从库确认
- 网络延迟,从库拉取 binlog 有延时
- 从库负载高,执行中继日志慢
- 大事务或慢查询导致执行阻塞
- IO 瓶颈,磁盘写入速度限制
- 复制线程阻塞,比如锁竞争或资源争用
-
这是分布式事务一致性问题,常用方案有:
- 补偿机制:失败后回滚 Redis 预检的操作(比如增加库存)
- 消息队列异步重试,确保数据库扣减最终完成
- 分布式事务框架(如 Seata)保证跨系统事务原子性
-
压测指标常见的有:
- TPS/QPS(每秒事务/请求数)
- 响应时间(平均、最大、百分位数,如P99)
- 错误率(失败请求占比)
- 系统资源利用率(CPU、内存、磁盘IO、网络带宽)
- 并发数(同时在线用户数或请求数)
- 基本逻辑:利用外部存储(Redis、Zookeeper等)作为锁的存储媒介,确保同一时刻只有一个客户端持有锁
- Redis分布式锁实现:通过
SET key value NX PX timeout命令原子性设置锁,使用唯一标识防止误释放 - 原理:利用原子操作和过期时间防止死锁和锁遗失
- Redlock 算法:多 Redis 实例实现更高可用和安全的分布式锁
- 大模型通常指参数量非常巨大的深度学习模型(如 GPT、BERT)
- 优点:具备强大的泛化和理解能力,支持多任务
- 挑战:训练成本高,推理慢,部署资源需求大
- 主要技术包括:模型压缩、蒸馏、分布式训练、多模态融合
-
瓶颈和压力点:
- 大量粉丝推送,消息并发量巨大,带宽和消息处理能力压力大
- 单点发送或数据库瓶颈导致推送延迟或失败
-
优化方案:
- 消息队列异步处理,削峰填谷
- 推模式改拉模式,结合用户在线状态分批拉取消息
- 分层缓存(Redis等)存储消息
- 使用CDN和分布式服务减少延迟
-
瓶颈:消息生产速度远超消费速度导致积压
-
解决措施:
- 扩容消费者,提高消费能力
- 优化消费逻辑,减少处理时间
- 限流或降级保护,防止流量暴涨
- 使用高性能消息队列(Kafka、RocketMQ)
- 分库分表:水平拆分减少单库压力
- 读写分离:写主库,读从库
- 缓存:用 Redis 缓存热点数据减少 DB 访问
- 批量写入:减少单次写操作次数
- 异步写入:通过消息队列缓冲写请求
- 优化索引和 SQL:避免全表扫描
Redis 三大缓存问题及解决方案
-
缓存穿透
-
问题:查询一个数据库中不存在的数据,缓存和数据库都没有,导致请求直接穿透到数据库,造成压力。
-
解决方案:
- 缓存空结果(比如缓存空对象,设置较短过期时间)
- 使用布隆过滤器(Bloom Filter)提前过滤不存在的请求
-
-
缓存击穿
-
问题:某个热点数据在缓存过期瞬间,大量请求同时到达数据库,造成数据库压力骤增。
-
解决方案:
- 使用互斥锁(分布式锁)保证只有一个请求去加载数据,其他等待
- 提前异步刷新热点数据,避免缓存失效瞬间大量请求
-
-
缓存雪崩
-
问题:大量缓存同时过期,导致大量请求直接访问数据库,可能导致数据库崩溃。
-
解决方案:
- 缓存过期时间加随机值,错开失效时间
- 多级缓存(本地缓存 + Redis)
- 采用降级策略或限流保护数据库
-
一句话总结:
缓存穿透防空结果或用布隆过滤器,缓存击穿用锁或提前加载,缓存雪崩用随机过期和多级缓存来解决。
布隆过滤器原理:
-
布隆过滤器是一种空间效率很高的概率型数据结构,用来判断一个元素是否可能存在于集合中。
-
它由一个位数组和多个哈希函数组成。
-
添加元素时:用多个哈希函数对元素进行哈希,得到多个数组下标,将对应位设为1。
-
查询元素时:用相同的哈希函数计算元素位置,检查对应位是否都为1。
- 如果有任意一位是0,说明元素一定不存在。
- 如果所有位都是1,说明元素可能存在(存在误判)。
特点
- 优点:空间和查询时间都很高效。
- 缺点:存在误判率(可能判断存在但实际不存在),但不会漏判(不存在判定为不存在)。
一句话总结:
布隆过滤器用多个哈希函数和位数组快速判断元素是否可能存在,牺牲少量准确性换取高效性能和低空间。
屏障的原理:
- 屏障允许多个线程在某个点相互等待,直到所有线程都达到这个点,才一起继续执行。
- 线程到达屏障时会阻塞,并增加计数器。
- 当计数器达到预设的线程数,屏障触发,所有等待的线程同时被释放。
- 这保证了所有线程在屏障点同步,防止部分线程提前执行。
常见实现:
- Java 中的
CyclicBarrier和CountDownLatch都是屏障的典型实现。 CyclicBarrier可以重复使用,支持线程达到屏障后执行一个回调动作。
一句话总结:
屏障通过计数等待所有线程达到同步点,确保线程集体同时继续执行。
- 装饰器(Decorator)
- 装饰器是一种函数,用来包装另一个函数,增强或修改其行为,不改变原函数代码。
- 通过**@语法糖**应用。
- 本质上是一个高阶函数,接收函数作为参数并返回一个新函数。
示例:
def decorator(func):
def wrapper():
print("Before call")
func()
print("After call")
return wrapper
@decorator
def say_hello():
print("Hello")
say_hello()- 列表表达式(List Comprehension)
- 用简洁语法创建列表,替代传统的 for 循环添加元素。
- 语法结构:
[表达式 for 变量 in 可迭代对象 if 条件]
示例:
squares = [x*x for x in range(10) if x % 2 == 0]
print(squares) # 输出 [0, 4, 16, 36, 64]一句话总结:
装饰器是包装函数,修改行为;列表表达式是快速生成列表的简洁语法。
- 200 OK:请求成功
- 301 Moved Permanently:永久重定向
- 302 Found:临时重定向
- 400 Bad Request:请求参数错误
- 401 Unauthorized:未授权
- 403 Forbidden:禁止访问
- 404 Not Found:资源未找到
- 500 Internal Server Error:服务器内部错误
- 503 Service Unavailable:服务不可用
- GET:请求获取资源,不改变服务器状态,幂等。
- POST:提交数据,可能创建资源或改变状态,不幂等。
- PUT:更新或创建资源,幂等。
- PUT 是幂等的,发送相同请求多次结果相同(通常更新资源)。
- POST 不幂等,发送多次可能创建多个资源或有不同效果。
- 高性能的反向代理服务器和负载均衡器,常用做静态资源服务器和反向代理。
- 将请求分发到多个后端服务器,提升系统吞吐和可靠性。
- 代理服务器接收客户端请求,将请求转发给后端服务器,隐藏真实服务器信息。
- 编辑配置文件(如
/etc/nginx/nginx.conf或sites-enabled下文件),修改后用命令nginx -t测试配置,最后执行nginx -s reload重载配置。
git log查看详细提交历史git log --oneline简洁模式
git reset --hard <commit_id>回退到指定版本(危险,慎用)git revert <commit_id>生成新提交,撤销某次提交
- 环境变量管理
- 脚本测试(Pre-request Script、Tests)
- Collection Runner 运行批量请求
- Mock Server 模拟接口
- 性能测试工具,用于压力测试、负载测试和功能测试,模拟多用户并发访问。
-
权限是控制用户对系统资源访问的规则。
-
通常通过**角色(Role)+ 权限(Permission)**模型管理。
-
主要方式有:
- 基于角色的访问控制(RBAC):用户绑定角色,角色有权限。
- 基于属性的访问控制(ABAC):根据用户属性、资源属性、环境等动态判断。
-
在系统中通过鉴权中间件或框架(如 Spring Security)实现权限校验。
@Transactional是 Spring 事务管理的声明式注解。- 通过**AOP(面向切面编程)**拦截标注方法,开启事务管理器管理的事务。
- 运行时,切面在方法调用前开启事务,方法正常结束提交事务,出现异常回滚事务。
- 底层依赖事务管理器(如
DataSourceTransactionManager)操作数据库连接和事务。
- Caffeine 是本地缓存,存储在应用内存,访问速度快,适合频繁读写的热数据,减少网络开销。
- Redis 是分布式缓存,跨进程共享,容量大,支持持久化和多实例,保证数据在多应用间一致。
- 结合使用,Caffeine 缓存热点数据提升性能,Redis 保证多服务数据共享和一致性。
- 用于全文搜索和分析,支持分布式、实时查询。
- 主要操作:索引管理、文档增删改查、DSL 查询、聚合分析。
- 常用场景:日志分析、电商搜索、推荐系统。
- 复现问题,查看日志和异常堆栈。
- 使用调试工具(IDE调试器、断点)定位。
- 打印关键信息,排除法定位。
- 结合版本控制回退对比代码。
- 使用监控系统查看系统指标。
- 容器化应用,镜像构建与管理。
- 主要命令:
docker build、docker run、docker ps、docker logs。 - Dockerfile 编写定义镜像。
- 容器编排(Docker Compose/Kubernetes)管理多容器应用。
- 代码层面优化(算法、数据结构、避免重复计算)。
- 数据库优化(索引、SQL调优、读写分离)。
- 缓存使用(本地缓存、分布式缓存)。
- 异步处理(消息队列、任务调度)。
- 资源监控与瓶颈分析。
- 可以结合时间和频率,如 LFU 或者 LRU+LFU 混合策略。
- 利用更高效的数据结构减少操作复杂度。
- 结合应用场景动态调整缓存容量。
- 常见瓶颈有数据库 IO、网络延迟、锁竞争、CPU 限制。
- 解决方法通常是拆分服务、分库分表、缓存、异步处理、水平扩展。
- 可靠的消息中间件,支持多种交换机类型(direct、fanout、topic)。
- 用于异步任务、削峰填谷、解耦服务。
- 支持消息确认、持久化、死信队列。
- 配合消费者限流和重试机制提高稳定性。
-
输入 URL 浏览器解析 URL,提取协议、域名、端口和路径。
-
DNS 解析 查询域名对应的 IP 地址,可能有本地缓存、系统缓存或向 DNS 服务器请求。
-
建立 TCP 连接 通过三次握手与服务器建立 TCP 连接。
-
发送 HTTP 请求 浏览器向服务器发送 HTTP 请求报文。
-
服务器响应 服务器返回 HTTP 响应,包括状态码、响应头和响应体(HTML 等)。
-
浏览器解析 HTML 解析 HTML,构建 DOM 树。
-
下载资源 解析过程中遇到 CSS、JS、图片等资源,浏览器发起并发请求下载。
-
构建 CSSOM 解析 CSS,生成 CSSOM 树。
-
生成渲染树 DOM 和 CSSOM 合并生成渲染树(Render Tree)。
-
布局(回流) 计算每个节点的几何信息(大小和位置)。
-
绘制(重绘) 根据渲染树绘制像素,显示到屏幕。
- 通过构建 DOM 和 CSSOM,生成渲染树。
- 计算布局信息,确定页面元素位置和尺寸。
- 将内容绘制到屏幕的图层上,完成页面渲染。
- JS 执行可能触发布局或重绘,动态更新页面。
read从文件或设备读取数据到用户空间缓冲区。write将用户空间数据写入文件或设备。- 这两个调用涉及内核态和用户态切换,数据一般会经过内核缓冲区。
- DMA(Direct Memory Access)允许硬件设备直接与内存交换数据,绕过 CPU,减少数据复制次数。
- 零拷贝技术利用 DMA 直接在用户缓冲区和设备间传输数据,提高效率,减少 CPU 负载。
- 用户态是运行应用程序的状态,内核态是运行操作系统核心代码的状态。
- 切换时 CPU 需保存当前状态,切换权限级别,执行内核代码(系统调用或中断处理),切换代价较高。
- 频繁切换会影响性能。
- 基于 QUIC 协议(UDP+多路复用+加密),替代 TCP,减少连接建立和传输延迟。
- 支持更快的连接恢复和拥塞控制。
- 更适合移动和不稳定网络环境。
- 带宽限制
- 网络延迟和丢包
- 服务器负载高或限速
- TCP 慢启动或拥塞控制影响
- DNS 解析慢
- 客户端性能限制或防火墙影响
- 技术栈是完成项目所用的所有技术集合,包括编程语言、框架、数据库、服务器、中间件等。
- 例如:前端(React)、后端(Spring Boot)、数据库(MySQL)、缓存(Redis)、消息队列(RabbitMQ)、容器(Docker)等。
- SQL 写法不规范(如函数操作字段、类型不匹配)
- 使用了范围查询后索引列右侧的索引失效
- 多列索引没有按照最左前缀原则使用
- 数据量太小导致全表扫描成本更低
- 统计信息不准,优化器选择全表扫描
- 通过
EXPLAIN查看查询执行计划,关注是否用到索引、扫描行数、连接方式等。 - 根据结果优化索引、SQL 结构、减少全表扫描和不必要的排序。
- 检查查询是否返回大量数据,优化分页或过滤条件。
- 复合索引设计是否合理。
- 确认服务器资源瓶颈(CPU、IO)。
- 可能需要优化表结构或分库分表。
- 场景:保证多个服务间对共享资源的互斥访问。
- 方案:使用 Redis 的
SET key value NX PX timeout实现原子加锁。 - 更好方案:Redlock 算法,多个 Redis 实例保证高可用和安全。
- Kubernetes 是容器编排平台,实现容器自动部署、扩缩容、负载均衡和管理。
- 核心组件有 Master(API Server、Scheduler)、Node(Kubelet、Container Runtime)等。
- 主要概念:Pod、Service、Deployment、ConfigMap、Ingress。
- Go 不支持直接比较两个 slice 是否相等。
- 需要遍历元素逐一比较长度和内容。
- Go 1.18+ 支持泛型,允许函数和类型接受任意类型参数。
- 用
type parameters声明,提升代码复用性和类型安全。
- 用于 goroutine 之间通信的管道,支持同步和异步消息传递。
- 用于传递取消信号、超时和请求范围的数据,常用于控制并发和请求生命周期。
- 用于监听多个 channel 的操作,支持超时和多路复用。
- 泛型支持
Fuzzing模糊测试内置支持Go Workspaces多模块管理- 性能和编译速度提升
- 利用线程并行最大化计算单元利用率
- 内存访问优化,减少全局内存访问,使用共享内存缓存数据
- 减少分支,避免线程发散
- 合理调度线程块和线程数量,充分利用硬件资源
- 使用异步拷贝和流水线技术重叠计算与数据传输
- 采用块状分割(blocking),分块加载数据进共享内存
- 利用寄存器缓存和共享内存减少内存访问延迟
- 线程协同计算,每个线程负责计算子矩阵的一部分
- 使用SIMD指令集和硬件加速特性
- 减少内存Bank冲突
- 共享内存分成多个bank,避免不同线程访问同一bank导致冲突
- 通过数据重排(padding)、改变访问模式,确保访问bank不冲突
- 设计合适的内存访问策略,使线程访问共享内存尽量均匀分布
- NVIDIA开源的高性能Transformer推理库
- 针对Transformer模型结构,做低精度计算(如FP16)、内存优化、并行化加速
- 输入:通常是
(batch_size, seq_length, embed_dim) - 输出与输入shape相同
(batch_size, seq_length, embed_dim) - 每层经过自注意力和前馈网络,shape保持不变
- 输入向量通过三个线性变换(矩阵乘法)分别生成 Query (Q)、Key (K)、Value (V)
- Q和K计算注意力权重,V加权求和得到输出
- 公式:
Attention(Q,K,V) = softmax(QK^T / sqrt(d_k)) * V
- 根据计算任务设计对应的CUDA核函数
- 设计时关注线程分配、内存访问模式和同步
- 优化计算密集度和内存带宽利用率
- 保证核函数内无竞态条件和最小线程发散
Transfer-Encoding: chunked表示服务器分块传输数据,不预先告知响应体长度。- 优点:可以边生成边发送,适合**流式传输、大文件或服务端渲染(SSR)**场景。
- 每个数据块前标注块长度,最后一个为
0\r\n\r\n表示结束。
- 宿主环境调度的任务,如:
setTimeout、setInterval、setImmediate、UI 渲染等。
- 当前宏任务执行完后立即执行的任务,如:
Promise.then、MutationObserver、queueMicrotask。
- 原生浏览器提供的消息通信机制,也可以用来实现微任务调度。
- 比
setTimeout更快,常用于polyfill 中模拟 nextTick 或异步更新 DOM。
-
原理:在 DOM 更新后执行回调。
-
内部用到了微任务优先调度机制,如:
Promise.then(现代浏览器)MutationObserver(兼容性)MessageChannel- 最后才是
setTimeout兜底。
-
主要作用:等 DOM 更新完之后再操作 DOM,避免拿到旧状态。
- 模块化管理:支持
import/export,解决 JS 依赖混乱问题 - 打包优化:将多个资源(JS/CSS/图片等)打包成优化后的静态文件
- 热更新(HMR):开发效率提升
- Tree Shaking:去除无用代码,减小包体积
- Loader & Plugin 系统:灵活扩展,适配各种资源编译(如 Babel、SASS)
- 预处理(Preprocessing):处理
#include、#define等宏指令 - 编译(Compiling):将
.cpp编译成.o,生成汇编或机器码 - 汇编(Assembling):生成目标文件
.o/.obj - 链接(Linking):把多个
.o和库文件合并成可执行文件
- 编译:生成目标文件,符号地址是相对的
- 链接:把各目标文件的符号连接起来
- 重定位:分配符号在最终可执行文件中的绝对地址
- 使用
__attribute__((always_inline))(GCC/Clang)强制内联 - 使用
#pragma inline(部分编译器支持) - 将函数定义写在类定义中(类内定义默认内联)
- 函数声明、类定义、常量定义、模板定义、inline函数
- 不能放函数的定义(除非是内联或模板),避免多重定义
- 禁止构造函数发生隐式类型转换
- 用于防止错误的自动类型转换行为,提升类型安全性
static_cast:安全的基本类型转换或向上转型dynamic_cast:用于类之间安全转换(需有虚函数)const_cast:去除 const/volatile 修饰reinterpret_cast:危险的底层强转(按内存位处理)
static_cast<double>→int64_t:值转换,浮点变整数reinterpret_cast:地址转换,不改变内容,只改变解释方式,会出错!
-
解决方法:
- 构造函数内使用智能指针(RAII)自动释放
- 分阶段构造,用工厂函数包装构造过程
- 捕获异常清理资源,避免内存泄漏
- 循环引用(shared_ptr 互指) → 用
weak_ptr解决 - 使用不当导致双重释放、悬空引用
unique_ptr不能复制,只能转移所有权- 不要用裸指针和智能指针混用
- 性能优化:现代 CPU 访问内存通常按对齐地址读取(如按 4 字节、8 字节块),非对齐访问会降低性能甚至导致异常。
- 硬件要求:某些平台不支持非对齐访问,可能会触发异常(如 ARM)。
- 对齐后的访问更快、更安全、能最大限度利用总线带宽。
-
推荐多进程:
- 更好地隔离资源,每个进程处理一部分文件,互不干扰。
- 能充分利用多核 CPU,并行读取多个文件块(结合 mmap / 分段读取)。
-
线程适用于内存数据量大但共享性强的场景,线程共享地址空间更轻量,但要注意同步。
- 稳定性好:进程间隔离,一个崩溃不会影响其他进程,避免级联故障。
- 扩展性强:天然支持横向扩展(加更多进程/节点),易于负载均衡。
- 常用于守护进程 + worker 模型,适合大并发、高可用系统(如 nginx、redis cluster)。
- CPU 有三级缓存(L1、L2、L3),层级越高,容量越大,访问速度越慢。
- 缓存原理是局部性原理(时间局部性、空间局部性)。
- 数据访问先查缓存,没命中则从主内存读取并写入缓存。
-
缓存一致性问题:多个 CPU 各自有缓存,会导致缓存失效或数据不同步。
-
解决方案:
- 总线锁/内存屏障:确保操作原子性与执行顺序
- MESI 协议:硬件协议同步各核缓存状态,避免数据不一致
- 软件层面使用锁(互斥锁、自旋锁、原子变量等)确保多核数据同步
- 避免 false sharing:不同核操作相邻内存地址时引发 cache line 冲突