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