Web应用开发 --- Tips
General
后端需要做参数校验
代码风格和Api设计风格的一致性大于正确性
一致的代码风格使团队所有成员都能快速理解代码
新成员加入时学习曲线更低
减少"这是谁写的代码?"这类困惑
长期成本考量
修复风格不一致的代价往往高于修复逻辑错误
风格混乱的代码库会持续产生维护成本
一致性差的代码在重构时风险更高
认知负荷理论
开发者大脑需要处理的风格差异越少,越能专注于业务逻辑
减少风格争议让团队把精力放在真正重要的架构问题上
数据入库时间应由后端记录
除非特殊情况,数据进入数据库的时间记录应是后端插入数据的时间
前端传来的时间是不可信的,比如两条数据传一样的时间,错误的时间等等情况
特别是有需要使用时间排序的情况
在对Api修改的时候,要注意兼容情况,避免breaking change
在对Api进行修改的时候,如改变Api的signature或在behavior时,要尽量避免breaking change,需要兼容老版本
索引
对于查询字段,注意加索引
对于唯一的字段,考虑加唯一索引
多线程
尽量优先使用线程安全工具,避免直接使用锁
在现代多线程编程中,直接使用锁(如synchronized、ReentrantLock等)虽然能解决问题,但会带来一些潜在风险和维护成本。更好的做法是优先使用线程安全的集合和其他封装好的并发工具
C#并发安全的集合
csharp
复制代码
ConcurrentDictionary<TKey, TValue>
ConcurrentQueue<T>
ConcurrentStack<T>
ConcurrentBag<T>
BlockingCollection<T>
c# 原子操作 (System.Threading.Interlocked)
csharp
复制代码
Interlocked.Increment(ref counter); // 原子递增
Interlocked.Decrement(ref counter); // 原子递减
Interlocked.Exchange(ref value, newValue); // 原子交换
Interlocked.CompareExchange(ref value, newValue, comparand); // 比较并交换
C# 任务并行库 (Task Parallel Library, TPL)
csharp
复制代码
//Parallel 类
Parallel.For(0, 100, i => {
// 并行执行的代码
});
Parallel.ForEach(collection, item => {
// 并行处理的代码
});
csharp
复制代码
//PLINQ (Parallel LINQ)
var results = data.AsParallel()
.Where(x => x > 0)
.Select(x => Process(x))
.ToList();
csharp
复制代码
//Task 类
Task.Run(() => {
// 后台执行的代码
});
var task1 = Task.Run(() => DoWork1());
var task2 = Task.Run(() => DoWork2());
Task.WaitAll(task1, task2); // 等待所有任务完成
csharp
复制代码
SemaphoreSlim // 轻量信号量
ReaderWriterLockSlim // 读写锁
ManualResetEventSlim // 轻量事件
csharp
复制代码
async Task<int> GetDataAsync()
{
var data = await httpClient.GetStringAsync(url);
return ProcessData(data);
}
注意线程的使用数量
在使用多线程的时候,需要预估和注意线程的数量. 过多的线程数量会导致资源紧张问题
比如一个发送消息的代码, 当taskNum过于大的时候,会导致大量的线程被创建,消耗资源
解决方案
思考是否真的需要多线程,可否不用
使用信号量控制线程数量
使用线程池控制线程数量
csharp
复制代码
public void Run(int taskNum)
{
var producerTasks = new Task[taskNum];
for (int i = 0; i < producerTasks.Length; i++)
{
int producerId = i + 1;
producerTasks[i] = Task.Run(() => ProducerThread(producerId));
}
}