backup materials and knowledge-base docs
This commit is contained in:
@@ -0,0 +1,308 @@
|
||||
# 常见错误模式
|
||||
|
||||
## 通用编程错误模式
|
||||
|
||||
### 1. Off-by-one Error(差一错误)
|
||||
|
||||
**描述**:循环或索引中出现 ±1 的偏差
|
||||
|
||||
**示例**:
|
||||
```python
|
||||
# ❌ 错误:范围应该是 range(n) 而不是 range(n+1)
|
||||
for i in range(len(items) + 1):
|
||||
print(items[i]) # IndexError
|
||||
|
||||
# ✅ 正确
|
||||
for i in range(len(items)):
|
||||
print(items[i])
|
||||
```
|
||||
|
||||
### 2. Null/None 引用错误
|
||||
|
||||
**描述**:尝试访问 None 对象的属性或方法
|
||||
|
||||
**Python**:
|
||||
```python
|
||||
# ❌ 可能返回 None
|
||||
result = get_data()
|
||||
print(result.value) # AttributeError
|
||||
|
||||
# ✅ 检查 None
|
||||
result = get_data()
|
||||
if result is not None:
|
||||
print(result.value)
|
||||
```
|
||||
|
||||
**JavaScript**:
|
||||
```javascript
|
||||
// ❌ 可能是 null
|
||||
const user = getUser();
|
||||
console.log(user.name); // TypeError
|
||||
|
||||
// ✅ 使用可选链
|
||||
console.log(user?.name);
|
||||
```
|
||||
|
||||
### 3. 资源泄漏
|
||||
|
||||
**描述**:打开的资源(文件、连接)未正确关闭
|
||||
|
||||
**Python**:
|
||||
```python
|
||||
# ❌ 文件可能未关闭
|
||||
f = open("file.txt")
|
||||
content = f.read()
|
||||
# 如果发生异常,文件不会关闭
|
||||
|
||||
# ✅ 使用 with 语句
|
||||
with open("file.txt") as f:
|
||||
content = f.read()
|
||||
# 文件自动关闭
|
||||
```
|
||||
|
||||
### 4. 竞态条件
|
||||
|
||||
**描述**:多线程/进程间的时序依赖问题
|
||||
|
||||
**示例**:
|
||||
```python
|
||||
# ❌ 检查后使用(TOCTOU)
|
||||
if os.path.exists("file.txt"):
|
||||
# 其他进程可能在这之间删除文件
|
||||
with open("file.txt") as f:
|
||||
content = f.read()
|
||||
|
||||
# ✅ 直接尝试并处理异常
|
||||
try:
|
||||
with open("file.txt") as f:
|
||||
content = f.read()
|
||||
except FileNotFoundError:
|
||||
content = None
|
||||
```
|
||||
|
||||
### 5. 忘记返回值
|
||||
|
||||
**描述**:函数没有显式返回值,导致返回 None
|
||||
|
||||
**示例**:
|
||||
```python
|
||||
# ❌ 忘记返回结果
|
||||
def calculate(x, y):
|
||||
result = x + y
|
||||
# 忘记 return
|
||||
|
||||
# ✅ 正确返回
|
||||
def calculate(x, y):
|
||||
return x + y
|
||||
```
|
||||
|
||||
### 6. 错误的比较运算符
|
||||
|
||||
**描述**:使用 = 代替 ==,或混淆 is 和 ==
|
||||
|
||||
**Python**:
|
||||
```python
|
||||
# ❌ 赋值而不是比较
|
||||
if x = 5: # SyntaxError
|
||||
|
||||
# ❌ 使用 is 比较值
|
||||
if x is 5: # 不保证正确
|
||||
|
||||
# ✅ 正确
|
||||
if x == 5:
|
||||
```
|
||||
|
||||
### 7. 浮点数精度问题
|
||||
|
||||
**描述**:浮点数比较因精度问题失败
|
||||
|
||||
**示例**:
|
||||
```python
|
||||
# ❌ 直接比较浮点数
|
||||
if 0.1 + 0.2 == 0.3: # False
|
||||
print("相等")
|
||||
|
||||
# ✅ 使用容差比较
|
||||
if abs((0.1 + 0.2) - 0.3) < 1e-9:
|
||||
print("相等")
|
||||
|
||||
# 或使用 math.isclose()
|
||||
import math
|
||||
if math.isclose(0.1 + 0.2, 0.3):
|
||||
print("相等")
|
||||
```
|
||||
|
||||
### 8. 字符串拼接性能问题
|
||||
|
||||
**描述**:在循环中使用 + 拼接字符串
|
||||
|
||||
**示例**:
|
||||
```python
|
||||
# ❌ 低效:每次创建新字符串
|
||||
result = ""
|
||||
for item in items:
|
||||
result += str(item)
|
||||
|
||||
# ✅ 高效:使用列表和 join
|
||||
result = "".join(str(item) for item in items)
|
||||
```
|
||||
|
||||
## Python 特有模式
|
||||
|
||||
### 1. 可变默认参数
|
||||
|
||||
```python
|
||||
# ❌ 所有调用共享同一个列表
|
||||
def append(item, items=[]):
|
||||
items.append(item)
|
||||
return items
|
||||
|
||||
# ✅ 使用 None 作为默认值
|
||||
def append(item, items=None):
|
||||
if items is None:
|
||||
items = []
|
||||
items.append(item)
|
||||
return items
|
||||
```
|
||||
|
||||
### 2. 闭包变量绑定问题
|
||||
|
||||
```python
|
||||
# ❌ 所有函数使用相同的 i 值
|
||||
funcs = [lambda: i for i in range(3)]
|
||||
# 所有函数都返回 2
|
||||
|
||||
# ✅ 使用默认参数捕获值
|
||||
funcs = [lambda i=i: i for i in range(3)]
|
||||
```
|
||||
|
||||
### 3. 修改正在迭代的序列
|
||||
|
||||
```python
|
||||
# ❌ 迭代时修改列表
|
||||
items = [1, 2, 3, 4]
|
||||
for item in items:
|
||||
if item % 2 == 0:
|
||||
items.remove(item)
|
||||
|
||||
# ✅ 创建新列表或使用副本
|
||||
items = [item for item in items if item % 2 != 0]
|
||||
|
||||
# 或
|
||||
for item in items[:]:
|
||||
if item % 2 == 0:
|
||||
items.remove(item)
|
||||
```
|
||||
|
||||
## JavaScript/TypeScript 特有模式
|
||||
|
||||
### 1. this 绑定问题
|
||||
|
||||
```javascript
|
||||
// ❌ this 丢失上下文
|
||||
class Counter {
|
||||
count = 0;
|
||||
increment() {
|
||||
setTimeout(function() {
|
||||
this.count++; // this 不是 Counter 实例
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ 使用箭头函数
|
||||
class Counter {
|
||||
count = 0;
|
||||
increment() {
|
||||
setTimeout(() => {
|
||||
this.count++; // this 正确绑定
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 异步错误处理
|
||||
|
||||
```javascript
|
||||
// ❌ 没有处理 Promise 错误
|
||||
async function getData() {
|
||||
const response = await fetch(url);
|
||||
return response.json(); // 如果失败会抛出异常
|
||||
}
|
||||
|
||||
// ✅ 使用 try-catch
|
||||
async function getData() {
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error("获取数据失败:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 数组/对象引用
|
||||
|
||||
```javascript
|
||||
// ❌ 直接赋值会复制引用
|
||||
const arr1 = [1, 2, 3];
|
||||
const arr2 = arr1;
|
||||
arr2.push(4); // arr1 也会被修改
|
||||
|
||||
// ✅ 创建副本
|
||||
const arr2 = [...arr1]; // 或 arr1.slice()
|
||||
|
||||
// 对象
|
||||
const obj1 = { a: 1 };
|
||||
const obj2 = { ...obj1 }; // 或 Object.assign({}, obj1)
|
||||
```
|
||||
|
||||
## 并发错误模式
|
||||
|
||||
### 1. 死锁
|
||||
|
||||
```python
|
||||
# ❌ 可能死锁
|
||||
import threading
|
||||
|
||||
lock1 = threading.Lock()
|
||||
lock2 = threading.Lock()
|
||||
|
||||
def thread1():
|
||||
with lock1:
|
||||
with lock2:
|
||||
# 操作
|
||||
|
||||
def thread2():
|
||||
with lock2:
|
||||
with lock1: # 死锁
|
||||
# 操作
|
||||
```
|
||||
|
||||
### 2. 数据竞争
|
||||
|
||||
```python
|
||||
# ❌ 多个线程同时修改共享变量
|
||||
counter = 0
|
||||
|
||||
def increment():
|
||||
global counter
|
||||
counter += 1 # 非原子操作
|
||||
|
||||
# ✅ 使用锁
|
||||
counter = 0
|
||||
lock = threading.Lock()
|
||||
|
||||
def increment():
|
||||
global counter
|
||||
with lock:
|
||||
counter += 1
|
||||
```
|
||||
|
||||
## 预防措施
|
||||
|
||||
1. **使用类型检查**:TypeScript、Python 类型注解
|
||||
2. **编写单元测试**:覆盖边界条件
|
||||
3. **使用静态分析工具**:pylint、eslint
|
||||
4. **代码审查**:让他人检查代码
|
||||
5. **使用防御性编程**:验证输入、处理异常
|
||||
Reference in New Issue
Block a user