后端面试题精选 — 高频题目解析

适用人群:后端开发者、面试准备
学习时长:约1周集中准备
覆盖语言:PHP/Python/Go/Java/Node.js

一、PHP 面试题

1.1 基础题

// Q1:PHP有哪些数据类型?
// A:标量:int、float、string、bool
//    复合:array、object
//    特殊:null、resource

// Q2:== 和 === 的区别?
// A:== 只比较值(会类型转换),=== 比较值和类型
"0" == false   // true
"0" === false  // false
0 == ""        // true
0 === ""       // false

// Q3:isset 和 empty 的区别?
// A:isset判断变量是否存在且不为null
//    empty判断变量是否为空(null、0、""、false、空数组)
$a = 0;
isset($a)   // true
empty($a)   // true

// Q4:Session 和 Cookie 的区别?
// A:Session存在服务端,Cookie存在客户端
//    Session更安全,Cookie有大小限制
//    Session依赖Cookie传递SessionID

// Q5:PHP的垃圾回收机制?
// A:引用计数 + 循环收集器
//    每个变量有引用计数,计数为0时回收
//    循环引用由循环收集器处理

1.2 进阶题

// Q1:如何防止SQL注入?
// A:使用预处理语句(PDO/MySQLi的prepare)
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$id]);

// Q2:PHP的Trait是什么?
// A:代码复用机制,解决单继承的局限性
trait Logger {
    public function log($msg) {
        echo $msg;
    }
}
class User {
    use Logger;
}

// Q3:什么是Composer?
// A:PHP的依赖管理工具,类似Node.js的npm
//    通过composer.json管理依赖
//    autoload自动加载类

// Q4:Laravel的服务容器是什么?
// A:依赖注入容器,管理类的依赖关系
//    自动解析和注入依赖
app()->bind('UserService', function() {
    return new UserService(new UserRepository());
});

// Q5:如何优化PHP性能?
// A:1. 使用OPcache缓存字节码
//    2. 使用Redis缓存
//    3. 数据库查询优化
//    4. 函数调用优化
//    5. 使用PHP 8.0+(JIT编译)


二、MySQL 面试题

2.1 基础题

-- Q1:MySQL有哪些存储引擎?
-- A:InnoDB(默认,支持事务、行锁)
--    MyISAM(不支持事务、表锁)
--    Memory(内存存储)

-- Q2:事务的ACID特性?
-- A:Atomicity(原子性):要么全部成功,要么全部回滚
--    Consistency(一致性):事务前后数据保持一致
--    Isolation(隔离性):并发事务互不干扰
--    Durability(持久性):提交后数据永久保存

-- Q3:MySQL的隔离级别?
-- A:READ UNCOMMITTED:可能脏读
--    READ COMMITTED:避免脏读
--    REPEATABLE READ:默认,避免脏读和不可重复读
--    SERIALIZABLE:最高隔离,性能最差

-- Q4:索引的类型?
-- A:主键索引、唯一索引、普通索引、全文索引、联合索引

-- Q5:什么是覆盖索引?
-- A:查询的列都在索引中,不需要回表
SELECT username FROM users WHERE username = '张三';

2.2 进阶题

-- Q1:如何优化慢查询?
-- A:1. EXPLAIN分析查询计划
--    2. 添加合适的索引
--    3. 避免SELECT *
--    4. 优化JOIN查询
--    5. 分页优化(游标分页)

-- Q2:什么是索引下推(ICP)?
-- A:MySQL 5.6+,在索引层面过滤数据,减少回表
SELECT * FROM users WHERE age > 20 AND name LIKE '张%';
-- 如果有(age, name)联合索引,可以在索引层面过滤

-- Q3:什么是N+1查询问题?
-- A:查询N条数据时,每条数据都单独查询关联表
-- 解决:使用JOIN或预加载
SELECT * FROM users u LEFT JOIN posts p ON u.id = p.user_id;

-- Q4:MySQL的主从复制原理?
-- A:1. Master写入binlog
--    2. Slave的IO线程读取binlog
--    3. Slave的SQL线程执行relay log

-- Q5:分库分表的策略?
-- A:垂直分库:按业务拆分
--    水平分表:按规则拆分数据
--    分片键选择、分布式ID生成


三、Redis 面试题

Q1:Redis有哪些数据类型?
A:String、List、Hash、Set、Sorted Set、Stream、HyperLogLog

Q2:Redis的持久化方式?
A:RDB(快照):定时保存数据快照
   AOF(日志):记录每个写操作
   混合持久化:RDB + AOF

Q3:什么是缓存穿透?
A:查询不存在的数据,缓存和数据库都没有
解决:缓存空值、布隆过滤器

Q4:什么是缓存击穿?
A:热点key过期,大量请求打到数据库
解决:互斥锁、永不过期

Q5:什么是缓存雪崩?
A:大量key同时过期,请求打到数据库
解决:随机过期时间、多级缓存

Q6:Redis的内存淘汰策略?
A:noeviction、allkeys-lru、volatile-lru、allkeys-random、volatile-random、volatile-ttl

Q7:Redis如何实现分布式锁?
A:SET key value NX EX 30
   释放锁:Lua脚本保证原子性


四、Go 面试题

// Q1:Go的并发模型是什么?
// A:CSP(Communicating Sequential Processes)
//    通过goroutine和channel实现并发

// Q2:goroutine和线程的区别?
// A:goroutine是用户态,创建成本低(几KB)
//    线程是内核态,创建成本高(几MB)
//    goroutine由Go运行时调度

// Q3:channel的类型?
// A:无缓冲channel:发送和接收同步
//    有缓冲channel:异步,缓冲区满时阻塞

// Q4:Go的interface是什么?
// A:方法集合,实现隐式接口
//    任何实现了接口方法的类型都实现了该接口

// Q5:Go的defer是什么?
// A:延迟执行,LIFO顺序
//    常用于资源释放、错误处理
func read() {
    f, _ := os.Open("file.txt")
    defer f.Close()  // 函数返回时执行
}

// Q6:Go的panic和recover?
// A:panic:运行时错误,程序崩溃
//    recover:捕获panic,恢复执行
func safe() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered:", r)
        }
    }()
    panic("error")
}


五、系统设计面试题

5.1 设计短链接系统

需求:
- 输入长URL,输出短URL
- 访问短URL重定向到长URL
- 支持10亿级URL

设计:
1. 生成短码:自增ID + Base62编码
2. 存储:MySQL(长URL → 短码)+ Redis缓存
3. 重定向:301永久重定向

优化:
- 分布式ID生成(雪花算法)
- 缓存热点URL
- 数据库分片

5.2 设计秒杀系统

需求:
- 商品限量100件
- 10万用户同时抢购
- 防止超卖

设计:
1. 前端:按钮防抖、CDN静态化
2. 网关:限流(令牌桶)
3. 库存预热:Redis预减库存
4. 异步下单:消息队列
5. 数据库:乐观锁防超卖

关键代码:
// Redis预减
if (redis.decr('stock:123') >= 0) {
    mq.send('order', {userId, productId})
}

// 数据库乐观锁
UPDATE products SET stock = stock - 1 
WHERE id = 123 AND stock > 0

5.3 设计微博系统

需求:
- 发布微博
- 关注/粉丝
- 首页时间线

设计:
1. 用户表、微博表、关注关系表
2. 发布:写入微博表 + 推送给粉丝
3. 首页:拉取关注人的最新微博

推拉模式:
- 推模式:发布时写入粉丝的收件箱
- 拉模式:读取时查询关注人的微博
- 推拉结合:大V用拉模式,普通用户用推模式


六、面试技巧

6.1 STAR法则

Situation:项目背景
Task:你的任务
Action:你的行动
Result:取得的成果

示例:
S:公司电商系统响应慢
T:负责优化API性能
A:添加Redis缓存、优化SQL查询、使用连接池
R:API响应时间从500ms降到50ms

6.2 反问面试官

- 团队的技术栈是什么?
- 日常工作流程是怎样的?
- 这个岗位的主要挑战?
- 团队规模和组织结构?
- 公司对新员工的培训?


学习建议

  1. 理解原理而不是背答案
  2. 结合实际项目经验回答
  3. 准备好项目的STAR描述
  4. 练习系统设计题的思路
  5. 保持诚实,不会的就说不会
返回首页