senior-backend
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSenior Backend Developer
资深后端开发工程师
Expert-level backend development for scalable systems.
面向可扩展系统的专家级后端开发内容。
Core Competencies
核心能力
- API design (REST, GraphQL, gRPC)
- Database design and optimization
- Microservices architecture
- Message queues and event-driven systems
- Caching strategies
- Authentication and authorization
- Performance optimization
- System observability
- API设计(REST、GraphQL、gRPC)
- 数据库设计与优化
- 微服务架构
- 消息队列与事件驱动系统
- 缓存策略
- 身份认证与授权
- 性能优化
- 系统可观测性
API Design
API设计
RESTful API Standards
RESTful API标准
URL Structure:
GET /api/v1/users # List
POST /api/v1/users # Create
GET /api/v1/users/:id # Read
PUT /api/v1/users/:id # Update (full)
PATCH /api/v1/users/:id # Update (partial)
DELETE /api/v1/users/:id # DeleteURL结构:
GET /api/v1/users # 列表
POST /api/v1/users # 创建
GET /api/v1/users/:id # 读取
PUT /api/v1/users/:id # 全量更新
PATCH /api/v1/users/:id # 部分更新
DELETE /api/v1/users/:id # 删除Nested resources
嵌套资源
GET /api/v1/users/:id/orders # User's orders
POST /api/v1/users/:id/orders # Create order for user
GET /api/v1/users/:id/orders # 用户订单
POST /api/v1/users/:id/orders # 为用户创建订单
Actions
自定义操作
POST /api/v1/users/:id/activate # Custom action
**Response Codes:**200 OK - Successful GET, PUT, PATCH
201 Created - Successful POST
204 No Content - Successful DELETE
400 Bad Request - Validation error
401 Unauthorized - Missing/invalid auth
403 Forbidden - Insufficient permissions
404 Not Found - Resource doesn't exist
409 Conflict - Resource conflict
422 Unprocessable - Semantic error
429 Too Many - Rate limit exceeded
500 Internal Error - Server error
**Standard Response Format:**
```json
{
"data": {},
"meta": {
"timestamp": "2024-01-15T10:30:00Z",
"requestId": "req_abc123"
},
"pagination": {
"page": 1,
"limit": 20,
"total": 100,
"hasMore": true
}
}Error Response Format:
json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{
"field": "email",
"message": "Must be a valid email address"
}
]
},
"meta": {
"timestamp": "2024-01-15T10:30:00Z",
"requestId": "req_abc123"
}
}POST /api/v1/users/:id/activate # 激活操作
**响应状态码:**200 OK - GET、PUT、PATCH请求成功
201 Created - POST请求成功
204 No Content - DELETE请求成功
400 Bad Request - 验证错误
401 Unauthorized - 身份认证缺失/无效
403 Forbidden - 权限不足
404 Not Found - 资源不存在
409 Conflict - 资源冲突
422 Unprocessable - 语义错误
429 Too Many - 请求频率超限
500 Internal Error - 服务器内部错误
**标准响应格式:**
```json
{
"data": {},
"meta": {
"timestamp": "2024-01-15T10:30:00Z",
"requestId": "req_abc123"
},
"pagination": {
"page": 1,
"limit": 20,
"total": 100,
"hasMore": true
}
}错误响应格式:
json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "请求验证失败",
"details": [
{
"field": "email",
"message": "必须是有效的邮箱地址"
}
]
},
"meta": {
"timestamp": "2024-01-15T10:30:00Z",
"requestId": "req_abc123"
}
}GraphQL Schema Design
GraphQL Schema设计
graphql
type Query {
user(id: ID!): User
users(filter: UserFilter, pagination: PaginationInput): UserConnection!
}
type Mutation {
createUser(input: CreateUserInput!): UserPayload!
updateUser(id: ID!, input: UpdateUserInput!): UserPayload!
deleteUser(id: ID!): DeletePayload!
}
type User {
id: ID!
email: String!
name: String!
role: Role!
posts(first: Int, after: String): PostConnection!
createdAt: DateTime!
}
type UserConnection {
edges: [UserEdge!]!
pageInfo: PageInfo!
totalCount: Int!
}
input CreateUserInput {
email: String!
name: String!
role: Role
}
type UserPayload {
user: User
errors: [Error!]
}graphql
type Query {
user(id: ID!): User
users(filter: UserFilter, pagination: PaginationInput): UserConnection!
}
type Mutation {
createUser(input: CreateUserInput!): UserPayload!
updateUser(id: ID!, input: UpdateUserInput!): UserPayload!
deleteUser(id: ID!): DeletePayload!
}
type User {
id: ID!
email: String!
name: String!
role: Role!
posts(first: Int, after: String): PostConnection!
createdAt: DateTime!
}
type UserConnection {
edges: [UserEdge!]!
pageInfo: PageInfo!
totalCount: Int!
}
input CreateUserInput {
email: String!
name: String!
role: Role
}
type UserPayload {
user: User
errors: [Error!]
}Database Design
数据库设计
Schema Design Principles
Schema设计原则
Normalization Levels:
- 1NF: Atomic values, no repeating groups
- 2NF: No partial dependencies
- 3NF: No transitive dependencies
- Consider denormalization for read performance
Naming Conventions:
sql
-- Tables: plural, snake_case
users, order_items, product_categories
-- Columns: singular, snake_case
user_id, created_at, is_active
-- Primary keys: id or table_id
id, user_id
-- Foreign keys: referenced_table_id
user_id, order_id
-- Indexes: idx_table_column
idx_users_email, idx_orders_created_at规范化级别:
- 1NF:原子值,无重复组
- 2NF:无部分依赖
- 3NF:无传递依赖
- 为提升读取性能可考虑反规范化
命名规范:
sql
-- 表名:复数、蛇形命名
users, order_items, product_categories
-- 列名:单数、蛇形命名
user_id, created_at, is_active
-- 主键:id或表名_id
id, user_id
-- 外键:关联表名_id
user_id, order_id
-- 索引:idx_表名_列名
idx_users_email, idx_orders_created_atPostgreSQL Patterns
PostgreSQL模式
Table Design:
sql
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
name VARCHAR(100) NOT NULL,
role VARCHAR(20) NOT NULL DEFAULT 'user',
is_active BOOLEAN NOT NULL DEFAULT true,
metadata JSONB,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_created_at ON users(created_at);
CREATE INDEX idx_users_metadata ON users USING GIN(metadata);
-- Updated_at trigger
CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER users_updated_at
BEFORE UPDATE ON users
FOR EACH ROW
EXECUTE FUNCTION update_updated_at();Common Queries:
sql
-- Pagination with cursor
SELECT * FROM users
WHERE created_at < $cursor_timestamp
ORDER BY created_at DESC
LIMIT $limit + 1;
-- Full-text search
SELECT * FROM products
WHERE search_vector @@ plainto_tsquery('english', $query)
ORDER BY ts_rank(search_vector, plainto_tsquery('english', $query)) DESC;
-- Aggregation with window functions
SELECT
user_id,
amount,
SUM(amount) OVER (PARTITION BY user_id ORDER BY created_at) as running_total
FROM orders;表设计:
sql
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
name VARCHAR(100) NOT NULL,
role VARCHAR(20) NOT NULL DEFAULT 'user',
is_active BOOLEAN NOT NULL DEFAULT true,
metadata JSONB,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_created_at ON users(created_at);
CREATE INDEX idx_users_metadata ON users USING GIN(metadata);
-- 更新时间触发器
CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER users_updated_at
BEFORE UPDATE ON users
FOR EACH ROW
EXECUTE FUNCTION update_updated_at();常用查询:
sql
-- 基于游标分页
SELECT * FROM users
WHERE created_at < $cursor_timestamp
ORDER BY created_at DESC
LIMIT $limit + 1;
-- 全文检索
SELECT * FROM products
WHERE search_vector @@ plainto_tsquery('english', $query)
ORDER BY ts_rank(search_vector, plainto_tsquery('english', $query)) DESC;
-- 窗口函数聚合
SELECT
user_id,
amount,
SUM(amount) OVER (PARTITION BY user_id ORDER BY created_at) as running_total
FROM orders;Query Optimization
查询优化
EXPLAIN ANALYZE:
sql
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT u.*, COUNT(o.id) as order_count
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE u.created_at > '2024-01-01'
GROUP BY u.id;Index Strategies:
sql
-- Composite index for common queries
CREATE INDEX idx_orders_user_status ON orders(user_id, status);
-- Partial index for filtered queries
CREATE INDEX idx_orders_pending ON orders(created_at)
WHERE status = 'pending';
-- Covering index to avoid table lookup
CREATE INDEX idx_users_email_name ON users(email) INCLUDE (name, role);EXPLAIN ANALYZE:
sql
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT u.*, COUNT(o.id) as order_count
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE u.created_at > '2024-01-01'
GROUP BY u.id;索引策略:
sql
-- 复合索引用于常用查询
CREATE INDEX idx_orders_user_status ON orders(user_id, status);
-- 部分索引用于过滤查询
CREATE INDEX idx_orders_pending ON orders(created_at)
WHERE status = 'pending';
-- 覆盖索引避免表查询
CREATE INDEX idx_users_email_name ON users(email) INCLUDE (name, role);Microservices
微服务
Service Boundaries
服务边界
Domain-Driven Design:
Bounded Contexts:
├── User Management
│ ├── Authentication
│ ├── User Profiles
│ └── Permissions
├── Order Processing
│ ├── Cart
│ ├── Checkout
│ └── Order History
├── Inventory
│ ├── Products
│ ├── Stock
│ └── Warehouses
└── Notifications
├── Email
├── SMS
└── PushCommunication Patterns:
Synchronous (HTTP/gRPC):
- Request/Response
- Query operations
- Real-time requirements
Asynchronous (Message Queue):
- Event notification
- Long-running tasks
- Cross-service data sync
领域驱动设计:
限界上下文:
├── 用户管理
│ ├── 身份认证
│ ├── 用户档案
│ └── 权限管理
├── 订单处理
│ ├── 购物车
│ ├── 结算
│ └── 订单历史
├── 库存管理
│ ├── 商品
│ ├── 库存
│ └── 仓库
└── 通知服务
├── 邮件
├── 短信
└── 推送通信模式:
同步(HTTP/gRPC):
- 请求/响应
- 查询操作
- 实时性需求
异步(消息队列):
- 事件通知
- 长时任务
- 跨服务数据同步
Event-Driven Architecture
事件驱动架构
Event Schema:
json
{
"id": "evt_abc123",
"type": "order.created",
"source": "order-service",
"time": "2024-01-15T10:30:00Z",
"data": {
"orderId": "ord_xyz789",
"userId": "usr_def456",
"total": 99.99,
"items": []
},
"metadata": {
"correlationId": "corr_123",
"version": "1.0"
}
}Event Handler:
typescript
class OrderEventHandler {
async handle(event: OrderCreatedEvent) {
switch (event.type) {
case 'order.created':
await this.handleOrderCreated(event.data);
break;
case 'order.paid':
await this.handleOrderPaid(event.data);
break;
}
}
private async handleOrderCreated(data: OrderData) {
// Reserve inventory
await this.inventoryService.reserve(data.items);
// Send confirmation email
await this.notificationService.sendOrderConfirmation(data);
}
}事件Schema:
json
{
"id": "evt_abc123",
"type": "order.created",
"source": "order-service",
"time": "2024-01-15T10:30:00Z",
"data": {
"orderId": "ord_xyz789",
"userId": "usr_def456",
"total": 99.99,
"items": []
},
"metadata": {
"correlationId": "corr_123",
"version": "1.0"
}
}事件处理器:
typescript
class OrderEventHandler {
async handle(event: OrderCreatedEvent) {
switch (event.type) {
case 'order.created':
await this.handleOrderCreated(event.data);
break;
case 'order.paid':
await this.handleOrderPaid(event.data);
break;
}
}
private async handleOrderCreated(data: OrderData) {
// 预留库存
await this.inventoryService.reserve(data.items);
// 发送确认邮件
await this.notificationService.sendOrderConfirmation(data);
}
}Caching
缓存
Caching Strategies
缓存策略
Cache-Aside:
typescript
async function getUser(id: string): Promise<User> {
const cacheKey = `user:${id}`;
// Try cache first
const cached = await redis.get(cacheKey);
if (cached) return JSON.parse(cached);
// Fetch from database
const user = await db.user.findUnique({ where: { id } });
// Store in cache
await redis.set(cacheKey, JSON.stringify(user), 'EX', 3600);
return user;
}Write-Through:
typescript
async function updateUser(id: string, data: UpdateUserData): Promise<User> {
// Update database
const user = await db.user.update({ where: { id }, data });
// Update cache
await redis.set(`user:${id}`, JSON.stringify(user), 'EX', 3600);
return user;
}Cache Invalidation:
typescript
async function invalidateUserCache(userId: string) {
await redis.del(`user:${userId}`);
await redis.del(`user:${userId}:orders`);
await redis.del(`user:${userId}:preferences`);
}旁路缓存:
typescript
async function getUser(id: string): Promise<User> {
const cacheKey = `user:${id}`;
// 先尝试从缓存获取
const cached = await redis.get(cacheKey);
if (cached) return JSON.parse(cached);
// 从数据库获取
const user = await db.user.findUnique({ where: { id } });
// 存入缓存
await redis.set(cacheKey, JSON.stringify(user), 'EX', 3600);
return user;
}写穿缓存:
typescript
async function updateUser(id: string, data: UpdateUserData): Promise<User> {
// 更新数据库
const user = await db.user.update({ where: { id }, data });
// 更新缓存
await redis.set(`user:${id}`, JSON.stringify(user), 'EX', 3600);
return user;
}缓存失效:
typescript
async function invalidateUserCache(userId: string) {
await redis.del(`user:${userId}`);
await redis.del(`user:${userId}:orders`);
await redis.del(`user:${userId}:preferences`);
}Redis Patterns
Redis模式
typescript
// Rate limiting
async function rateLimit(key: string, limit: number, window: number): Promise<boolean> {
const current = await redis.incr(key);
if (current === 1) {
await redis.expire(key, window);
}
return current <= limit;
}
// Distributed lock
async function acquireLock(key: string, ttl: number): Promise<boolean> {
const result = await redis.set(key, '1', 'NX', 'EX', ttl);
return result === 'OK';
}
// Pub/Sub
const publisher = redis.duplicate();
const subscriber = redis.duplicate();
await subscriber.subscribe('events');
subscriber.on('message', (channel, message) => {
console.log(`Received: ${message}`);
});
await publisher.publish('events', JSON.stringify({ type: 'test' }));typescript
// 请求频率限制
async function rateLimit(key: string, limit: number, window: number): Promise<boolean> {
const current = await redis.incr(key);
if (current === 1) {
await redis.expire(key, window);
}
return current <= limit;
}
// 分布式锁
async function acquireLock(key: string, ttl: number): Promise<boolean> {
const result = await redis.set(key, '1', 'NX', 'EX', ttl);
return result === 'OK';
}
// 发布/订阅
const publisher = redis.duplicate();
const subscriber = redis.duplicate();
await subscriber.subscribe('events');
subscriber.on('message', (channel, message) => {
console.log(`Received: ${message}`);
});
await publisher.publish('events', JSON.stringify({ type: 'test' }));Authentication
身份认证
JWT Implementation
JWT实现
typescript
import jwt from 'jsonwebtoken';
interface TokenPayload {
userId: string;
role: string;
sessionId: string;
}
function generateTokens(user: User) {
const accessToken = jwt.sign(
{ userId: user.id, role: user.role, sessionId: generateId() },
process.env.JWT_SECRET,
{ expiresIn: '15m' }
);
const refreshToken = jwt.sign(
{ userId: user.id, sessionId: generateId() },
process.env.JWT_REFRESH_SECRET,
{ expiresIn: '7d' }
);
return { accessToken, refreshToken };
}
function verifyAccessToken(token: string): TokenPayload {
return jwt.verify(token, process.env.JWT_SECRET) as TokenPayload;
}
async function refreshAccessToken(refreshToken: string) {
const payload = jwt.verify(refreshToken, process.env.JWT_REFRESH_SECRET);
// Verify session still valid
const session = await redis.get(`session:${payload.sessionId}`);
if (!session) throw new Error('Session expired');
const user = await db.user.findUnique({ where: { id: payload.userId } });
return generateTokens(user);
}typescript
import jwt from 'jsonwebtoken';
interface TokenPayload {
userId: string;
role: string;
sessionId: string;
}
function generateTokens(user: User) {
const accessToken = jwt.sign(
{ userId: user.id, role: user.role, sessionId: generateId() },
process.env.JWT_SECRET,
{ expiresIn: '15m' }
);
const refreshToken = jwt.sign(
{ userId: user.id, sessionId: generateId() },
process.env.JWT_REFRESH_SECRET,
{ expiresIn: '7d' }
);
return { accessToken, refreshToken };
}
function verifyAccessToken(token: string): TokenPayload {
return jwt.verify(token, process.env.JWT_SECRET) as TokenPayload;
}
async function refreshAccessToken(refreshToken: string) {
const payload = jwt.verify(refreshToken, process.env.JWT_REFRESH_SECRET);
// 验证会话是否有效
const session = await redis.get(`session:${payload.sessionId}`);
if (!session) throw new Error('Session expired');
const user = await db.user.findUnique({ where: { id: payload.userId } });
return generateTokens(user);
}Authorization Middleware
授权中间件
typescript
function authorize(...allowedRoles: string[]) {
return async (req: Request, res: Response, next: NextFunction) => {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) {
return res.status(401).json({ error: 'No token provided' });
}
try {
const payload = verifyAccessToken(token);
if (!allowedRoles.includes(payload.role)) {
return res.status(403).json({ error: 'Insufficient permissions' });
}
req.user = payload;
next();
} catch (error) {
return res.status(401).json({ error: 'Invalid token' });
}
};
}
// Usage
app.get('/admin/users', authorize('admin'), listUsers);
app.get('/users/me', authorize('user', 'admin'), getProfile);typescript
function authorize(...allowedRoles: string[]) {
return async (req: Request, res: Response, next: NextFunction) => {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) {
return res.status(401).json({ error: 'No token provided' });
}
try {
const payload = verifyAccessToken(token);
if (!allowedRoles.includes(payload.role)) {
return res.status(403).json({ error: 'Insufficient permissions' });
}
req.user = payload;
next();
} catch (error) {
return res.status(401).json({ error: 'Invalid token' });
}
};
}
// 使用示例
app.get('/admin/users', authorize('admin'), listUsers);
app.get('/users/me', authorize('user', 'admin'), getProfile);Observability
可观测性
Logging
日志
typescript
import pino from 'pino';
const logger = pino({
level: process.env.LOG_LEVEL || 'info',
formatters: {
level: (label) => ({ level: label }),
},
base: {
service: 'user-service',
environment: process.env.NODE_ENV,
},
});
// Structured logging
logger.info({ userId, action: 'login' }, 'User logged in');
logger.error({ error, requestId }, 'Request failed');
// Request logging middleware
function requestLogger(req: Request, res: Response, next: NextFunction) {
const start = Date.now();
const requestId = generateRequestId();
req.log = logger.child({ requestId });
res.on('finish', () => {
const duration = Date.now() - start;
req.log.info({
method: req.method,
path: req.path,
statusCode: res.statusCode,
duration,
}, 'Request completed');
});
next();
}typescript
import pino from 'pino';
const logger = pino({
level: process.env.LOG_LEVEL || 'info',
formatters: {
level: (label) => ({ level: label }),
},
base: {
service: 'user-service',
environment: process.env.NODE_ENV,
},
});
// 结构化日志
logger.info({ userId, action: 'login' }, 'User logged in');
logger.error({ error, requestId }, 'Request failed');
// 请求日志中间件
function requestLogger(req: Request, res: Response, next: NextFunction) {
const start = Date.now();
const requestId = generateRequestId();
req.log = logger.child({ requestId });
res.on('finish', () => {
const duration = Date.now() - start;
req.log.info({
method: req.method,
path: req.path,
statusCode: res.statusCode,
duration,
}, 'Request completed');
});
next();
}Metrics
指标
typescript
import { Registry, Counter, Histogram } from 'prom-client';
const registry = new Registry();
const httpRequestsTotal = new Counter({
name: 'http_requests_total',
help: 'Total HTTP requests',
labelNames: ['method', 'path', 'status'],
registers: [registry],
});
const httpRequestDuration = new Histogram({
name: 'http_request_duration_seconds',
help: 'HTTP request duration',
labelNames: ['method', 'path'],
buckets: [0.01, 0.05, 0.1, 0.5, 1, 5],
registers: [registry],
});
// Middleware
function metricsMiddleware(req: Request, res: Response, next: NextFunction) {
const end = httpRequestDuration.startTimer({ method: req.method, path: req.route?.path });
res.on('finish', () => {
end();
httpRequestsTotal.inc({
method: req.method,
path: req.route?.path,
status: res.statusCode,
});
});
next();
}typescript
import { Registry, Counter, Histogram } from 'prom-client';
const registry = new Registry();
const httpRequestsTotal = new Counter({
name: 'http_requests_total',
help: 'Total HTTP requests',
labelNames: ['method', 'path', 'status'],
registers: [registry],
});
const httpRequestDuration = new Histogram({
name: 'http_request_duration_seconds',
help: 'HTTP request duration',
labelNames: ['method', 'path'],
buckets: [0.01, 0.05, 0.1, 0.5, 1, 5],
registers: [registry],
});
// 中间件
function metricsMiddleware(req: Request, res: Response, next: NextFunction) {
const end = httpRequestDuration.startTimer({ method: req.method, path: req.route?.path });
res.on('finish', () => {
end();
httpRequestsTotal.inc({
method: req.method,
path: req.route?.path,
status: res.statusCode,
});
});
next();
}Reference Materials
参考资料
- - API design guidelines
references/api_design.md - - Database optimization
references/database_patterns.md - - Service architecture
references/microservices.md - - Security best practices
references/security.md
- - API设计指南
references/api_design.md - - 数据库优化
references/database_patterns.md - - 服务架构
references/microservices.md - - 安全最佳实践
references/security.md
Scripts
脚本
bash
undefinedbash
undefinedAPI scaffolder
API脚手架
python scripts/api_scaffold.py --name user --crud
python scripts/api_scaffold.py --name user --crud
Database migration generator
数据库迁移生成器
python scripts/db_migrate.py --name add_user_roles
python scripts/db_migrate.py --name add_user_roles
Load testing
负载测试
python scripts/load_test.py --endpoint /api/users --rps 100
python scripts/load_test.py --endpoint /api/users --rps 100
Service health checker
服务健康检查器
python scripts/health_check.py --services services.yaml
undefinedpython scripts/health_check.py --services services.yaml
undefined