Skip to content

Latest commit

 

History

History
672 lines (482 loc) · 14.1 KB

File metadata and controls

672 lines (482 loc) · 14.1 KB

常见问题 FAQ

📍 导航返回首页 | 参考资源 | 术语表


📖 学习相关

Q1:我是零基础,应该如何开始学习后台开发?

A:建议按以下路径:

第1阶段(1-2个月)

  1. 学习一门编程语言:推荐GoPython
  2. 掌握Linux基础命令
  3. 学习基本的数据结构与算法

第2阶段(2-3个月): 4. 深入学习选定的语言(Go并发模型/Python异步编程) 5. 学习数据库(MySQL基础) 6. 学习Redis缓存

第3阶段(3-6个月): 7. 学习分布式系统理论 8. 学习微服务架构 9. 实战项目:构建一个完整的后台服务

推荐起点docs/part1-fundamentals/


Q2:本指南内容很多,应该全部学完吗?

A不需要全部学完。根据你的职业阶段选择性学习:

  • 初级工程师:重点第1-4章(基础、语言、中间件基础、算法)
  • 中级工程师:第5-6章(分布式系统、微服务)
  • 高级工程师:第7-10章(系统设计、云原生、安全、工程实践)

建议:先学好基础,再逐步深入。


Q3:学完本指南大概需要多长时间?

A:因人而异,参考时间:

  • 快速浏览:1-2周(了解大概)
  • 系统学习:3-6个月(配合实践)
  • 深入掌握:1-2年(结合工作经验)

关键理论+实践结合,不要只看不练。


Q4:为什么选择Go作为主要示例语言?

A:原因如下:

  1. 云原生首选:Docker、K8s、etcd等都用Go编写
  2. 并发简单:goroutine比线程更轻量
  3. 性能优秀:接近C++,远超Python/Java
  4. 学习曲线平缓:语法简洁,易于上手
  5. 就业市场好:后台岗位Go需求旺盛

但也推荐:Python(脚本、数据处理)、Java(传统企业)


🛠️ 技术选型相关

Q5:Redis vs Memcached,如何选择?

A:推荐Redis

特性 Redis Memcached
数据结构 丰富(String/List/Set/Hash/ZSet) 仅String
持久化 支持(RDB/AOF) 不支持
主从复制 支持 不支持
事务 支持 不支持
Lua脚本 支持 不支持
性能 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐

结论:Redis功能更强大,Memcached仅在纯KV缓存且不需持久化时考虑。


Q6:MySQL vs PostgreSQL,如何选择?

A

选MySQL

  • ✅ 生态成熟(工具、教程丰富)
  • ✅ 互联网公司主流
  • ✅ 分库分表方案成熟

选PostgreSQL

  • ✅ 功能更强大(JSON、全文检索、GIS)
  • ✅ SQL标准支持更好
  • ✅ 复杂查询性能更优

建议:互联网公司选MySQL,传统企业/复杂业务选PostgreSQL。


Q7:Kafka vs RabbitMQ vs RocketMQ,如何选择?

A

场景 推荐MQ 理由
日志收集、大数据 Kafka 高吞吐量(百万级TPS)
传统企业、中小规模 RabbitMQ 功能丰富,易用
电商、金融(国内) RocketMQ 事务消息、顺序消息

性能对比

  • Kafka:百万级TPS
  • RocketMQ:十万级TPS
  • RabbitMQ:万级TPS

Q8:微服务一定比单体好吗?

A不一定

单体应用适用于

  • 团队规模小(<10人)
  • 业务相对简单
  • 快速迭代阶段
  • 技术栈统一

微服务适用于

  • 团队规模大(>20人)
  • 业务复杂,模块众多
  • 需要独立扩展
  • 技术栈异构

建议:从单体开始,业务复杂后再拆分微服务("单体优先"策略)。


💻 编程实践相关

Q9:如何提升编程能力?

A

1. 刻意练习

  • LeetCode刷题(每天1-2道)
  • 实现经典数据结构和算法
  • 阅读优秀开源项目源码

2. 项目驱动

  • 做完整的实战项目
  • 从0到1搭建系统
  • 模拟生产环境问题

3. 持续输出

  • 写技术博客
  • 参与开源贡献
  • 技术分享

Q10:如何阅读源码?

A

入门级项目(代码量<1万行):

  • groupcache、go-cache
  • 从main函数开始,跟踪主流程

进阶级项目(代码量1-10万行):

  • etcd、TiDB
  • 先看架构文档,再看核心模块

专家级项目(代码量10万+行):

  • Kubernetes、MySQL
  • 选择特定模块深入研究

技巧

  1. 先运行起来,调试跟踪
  2. 画出模块依赖图
  3. 从测试代码入手
  4. 关注设计模式和架构思想

🔧 工具使用相关

Q11:如何快速定位CPU 100%的问题?

A

步骤1:定位进程

top  # 查看哪个进程CPU高

步骤2:查看线程

top -H -p <pid>  # 查看该进程的线程

步骤3:查看调用栈

# Go程序
curl http://localhost:6060/debug/pprof/goroutine?debug=1

# C++/Java
pstack <pid>
jstack <pid>

步骤4:性能分析

# Go程序
go tool pprof http://localhost:6060/debug/pprof/profile

# Linux通用
perf record -p <pid> -g -- sleep 30
perf report

Q12:如何排查内存泄漏?

A

Go程序

# 1. 开启pprof
import _ "net/http/pprof"

# 2. 采样堆内存
go tool pprof http://localhost:6060/debug/pprof/heap

# 3. 查看top占用
(pprof) top10
(pprof) list <function_name>

C++程序

valgrind --leak-check=full --show-leak-kinds=all ./app

Python程序

import tracemalloc
tracemalloc.start()
# ... 运行代码
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')

Q13:如何进行性能压测?

A

HTTP压测

# wrk(推荐)
wrk -t12 -c400 -d30s http://localhost:8080/api

# ab
ab -n 10000 -c 100 http://localhost:8080/

关键指标

  • QPS:每秒请求数
  • 延迟:P50、P95、P99、P999
  • 错误率:5xx错误占比

注意事项

  1. 先预热(避免冷启动影响)
  2. 逐步增加并发(找到拐点)
  3. 监控系统资源(CPU、内存、网络)
  4. 记录详细数据(写压测报告)

🏢 职业发展相关

Q14:后台开发工程师职业路径是什么?

A

技术路线

初级工程师(0-2年)
  ↓
中级工程师(2-5年)
  ↓
高级工程师(5-8年)
  ↓
资深工程师/技术专家(8年+)
  ↓
架构师/Fellow

管理路线

高级工程师
  ↓
Tech Lead(技术负责人)
  ↓
技术经理
  ↓
技术总监/CTO

Q15:如何准备后台开发面试?

A

准备清单

1. 基础知识(必问):

  • 操作系统(进程/线程、内存管理、IO)
  • 网络(TCP/IP、HTTP、WebSocket)
  • 数据库(MySQL索引、事务)
  • Redis(数据结构、持久化)

2. 算法(必考):

  • 刷LeetCode 200+题
  • 重点:数组、链表、树、动态规划

3. 系统设计(高级必考):

  • 设计短链接系统
  • 设计秒杀系统
  • 设计Feed流系统

4. 项目经验

  • 准备2-3个项目深入讲解
  • 突出技术难点和你的贡献
  • 准备性能优化案例

资源


🐛 问题排查相关

Q16:线上服务突然变慢,如何排查?

A

排查清单

1. 查看监控大盘

  • CPU、内存、磁盘IO、网络
  • 请求量、错误率、延迟

2. 查看日志

  • 错误日志(ERROR级别)
  • 慢查询日志(数据库)
  • GC日志(Go/Java)

3. 性能分析

# CPU profiling
curl http://localhost:6060/debug/pprof/profile?seconds=30 > cpu.prof
go tool pprof cpu.prof

# 查看goroutine
curl http://localhost:6060/debug/pprof/goroutine?debug=1

4. 数据库检查

-- MySQL慢查询
SHOW PROCESSLIST;
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;  -- 长事务

5. 缓存检查

# Redis
redis-cli INFO stats
redis-cli SLOWLOG GET 10

Q17:如何处理数据库死锁?

A

定位死锁

SHOW ENGINE INNODB STATUS;

死锁预防

  1. 按固定顺序访问资源
  2. 减少事务持有锁的时间
  3. 使用乐观锁(version字段)
  4. 合理设置隔离级别

示例

// ❌ 可能死锁
func Transfer(from, to int64, amount decimal.Decimal) error {
    tx.Exec("UPDATE accounts SET balance = balance - ? WHERE id = ?", amount, from)
    tx.Exec("UPDATE accounts SET balance = balance + ? WHERE id = ?", amount, to)
}

// ✅ 固定顺序,避免死锁
func Transfer(from, to int64, amount decimal.Decimal) error {
    // 总是先锁ID小的
    if from > to {
        from, to = to, from
        amount = -amount
    }
    tx.Exec("UPDATE accounts SET balance = balance - ? WHERE id = ?", amount, from)
    tx.Exec("UPDATE accounts SET balance = balance + ? WHERE id = ?", amount, to)
}

🔒 安全相关

Q18:如何防止SQL注入?

A

✅ 正确做法:使用参数化查询

// Go
rows, err := db.Query("SELECT * FROM users WHERE name = ?", userName)

// Python
cursor.execute("SELECT * FROM users WHERE name = %s", (user_name,))

❌ 错误做法:字符串拼接

// 危险!容易SQL注入
query := fmt.Sprintf("SELECT * FROM users WHERE name = '%s'", userName)
db.Query(query)

ORM也要注意

// ✅ 安全
db.Where("name = ?", userName).Find(&users)

// ❌ 不安全(Raw SQL)
db.Raw("SELECT * FROM users WHERE name = '" + userName + "'").Scan(&users)

Q19:JWT vs Session,如何选择?

A

特性 JWT Session
状态 无状态 有状态
扩展性 易于水平扩展 需要Session共享
性能 每次请求需验证签名 查Redis/内存
安全性 Token泄露风险 Session ID泄露
适用场景 微服务、分布式 单体应用

推荐

  • 大规模分布式系统:JWT
  • 小规模应用:Session
  • 混合方案:短期用Session,长期用JWT(如移动App)

📊 性能优化相关

Q20:如何提升接口性能?

A

优化清单

1. 缓存优化(最有效):

用户请求 → 查Redis缓存(命中率>90%)
            ↓ 未命中
           查MySQL → 写回缓存

2. 数据库优化

  • 添加索引(慢查询)
  • 优化SQL(避免全表扫描)
  • 使用连接池
  • 读写分离

3. 代码优化

  • 减少不必要的系统调用
  • 批量操作(批量插入、Pipeline)
  • 异步处理(消息队列)
  • 对象池复用

4. 架构优化

  • CDN加速
  • 负载均衡
  • 微服务拆分
  • 数据库分库分表

优化顺序:先缓存,再数据库,后代码,最后架构。


Q21:什么时候需要分库分表?

A

触发条件(满足任一即可考虑):

  • 单表数据量 > 1000万
  • 单库QPS > 3000
  • 单表磁盘空间 > 20GB
  • 查询响应时间 > 100ms

策略选择

  • 垂直拆分:按业务模块拆分(订单库、用户库)
  • 水平拆分:按数据拆分(用户ID取模)

注意

  • ⚠️ 增加复杂度(跨库查询、分布式事务)
  • ⚠️ 运维成本增加
  • 💡 先尝试读写分离、缓存优化

🎯 架构设计相关

Q22:如何设计一个秒杀系统?

A

核心思路

  1. 页面静态化:CDN分发
  2. Redis预扣库存:内存操作,性能极高
  3. 消息队列削峰:异步创建订单
  4. 分布式锁:防止超卖

详细方案:见7.1 秒杀系统设计


Q23:如何保证接口幂等性?

A

幂等性:多次调用产生的结果与一次调用相同。

实现方案

方案1:唯一索引

CREATE UNIQUE INDEX idx_order_no ON orders(order_no);
-- 重复插入会报错

方案2:Token机制

// 1. 生成Token
token := generateToken()
redis.Set("token:"+token, "1", 5*time.Minute)

// 2. 提交时验证Token(Lua脚本保证原子性)
script := `
    if redis.call('exists', KEYS[1]) == 1 then
        redis.call('del', KEYS[1])
        return 1
    else
        return 0
    end
`
result := redis.Eval(script, []string{"token:" + token})
if result == 0 {
    return errors.New("token已使用或过期")
}

方案3:状态机

订单状态:待支付 → 已支付 → 已发货
只能单向流转,重复调用无影响

❓ 其他常见问题

Q24:Go的GC会影响性能吗?

A

会有影响,但可控

  • Go 1.19+的GC已经非常优秀(STW <1ms)
  • 大部分场景下GC不是瓶颈

优化建议

  1. 减少堆分配:使用对象池、栈分配
  2. 调整GOGCGOGC=200(默认100)
  3. 使用pprof分析:找出分配热点

何时需要担心GC

  • 极低延迟要求(<1ms)
  • 大内存应用(>10GB)
  • 高频对象分配

Q25:Docker vs 虚拟机,有什么区别?

A

特性 Docker容器 虚拟机
启动速度 秒级 分钟级
资源占用 轻量(MB级) 重(GB级)
隔离性 进程级 操作系统级
性能 接近原生 有损耗
适用场景 微服务、CI/CD 需要完全隔离

结论:现代应用优先选择容器。


Q26:如何选择云服务商?

A

考虑因素

  1. 成本:计算、存储、流量费用
  2. 地域:数据中心位置(影响延迟)
  3. 服务完整性:是否有需要的PaaS服务
  4. 技术支持:服务响应速度
  5. 生态:社区、文档、案例

国内推荐

  • 阿里云:生态最完善,适合互联网
  • 腾讯云:游戏、社交场景强
  • 华为云:政企市场强

💬 如何提问

如果你的问题未在此列表中,欢迎:

  1. 提交GitHub Issue
  2. 参与社区讨论
  3. 贡献FAQ内容

提示:本FAQ持续更新,欢迎补充新问题!


返回首页 | 参考资源 | 术语表