NumPy: 随机数

随机数

1. 你将学到

❶ Generator vs RandomState ❷ 常见分布 ❸ 随机种子 ❹ choice / permute / shuffle ❺ 蒙特卡洛入门


2. 一个开发者的真实故事

(1) 痛点

Bob 问"掷 1000 次骰子出现 3 个 6 的概率?"他翻概率论课本找二项分布公式,算了半天还怕算错。

(2) 解法

Alice 用 rng.binomial(1000, 1/6, size=100000) 1 行搞定——"不用查公式,直接模拟 10 万次。"

(3) 收益

Bob 发现蒙特卡洛方法把复杂的概率问题变成了"模拟 + 计数",无需推导公式也能得到高精度答案。


3. Generator API

(1) 为什么用 default_rng

NumPy 1.17 引入了全新的随机数体系——default_rng() 返回 Generator 对象,替代旧版 np.random.RandomState

对比项 Generator(新版) RandomState(旧版)
创建方式 rng = np.random.default_rng() rng = np.random.RandomState()
默认算法 PCG64(高质量、快速) MT19937(Mersenne Twister)
流式设计 独立 Generator 实例,互不干扰 全局状态,np.random.seed() 影响全部
采样函数 rng.integers()rng.random() np.random.randint()np.random.rand()
可扩展性 支持自定义 BitGenerator 不支持
推荐度 ✅ 官方推荐 ⚠️ 仅向后兼容

(2) default_rng 基本用法

PYTHON
import numpy as np

rng = np.random.default_rng()

# Float in [0, 1)
print(rng.random(5))
# [0.345 0.789 0.123 0.567 0.901]

# Integers in [low, high)
print(rng.integers(1, 7, size=10))
# [3 6 1 5 2 4 6 1 3 5]

# Standard normal
print(rng.standard_normal(5))
# [ 0.123 -1.456  2.345  0.789 -0.234]
TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

▶ 示例

TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

:Generator 基本用法(难度⭐)

PYTHON
import numpy as np

rng = np.random.default_rng(seed=42)

# Generate integers: dice rolls
dice = rng.integers(1, 7, size=20)
print("Dice rolls:", dice)
# Dice rolls: [1 2 2 2 6 3 4 5 1 3 5 2 6 6 1 5 6 5 2 3]

# Generate floats in [0, 1)
probs = rng.random(5)
print("Random probs:", probs)
# Random probs: [0.774 0.438 0.859 0.697 0.094]

# Generate 2D array
matrix = rng.integers(0, 100, size=(3, 4))
print("3x4 matrix:\n", matrix)
# 3x4 matrix:
#  [[51 92 14 71]
#   [60 20 82 86]
#   [74 74 87 99]]
TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

4. 常见分布

(1) 分布速查表

分布 方法 参数 值域 典型场景
均匀(连续) rng.random(size) 无([0,1)) [0, 1) 随机概率
均匀(整数) rng.integers(low, high, size) low, high [low, high) 骰子、随机索引
正态 rng.standard_normal(size) 无(μ=0, σ=1) (-∞, +∞) 测量误差
正态(自定义) rng.normal(loc, scale, size) μ, σ (-∞, +∞) 身高分布
二项 rng.binomial(n, p, size) 试验次数, 成功概率 {0,1,...,n} 抛硬币、骰子
泊松 rng.poisson(lam, size) λ(期望) {0,1,2,...} 单位时间事件数
指数 rng.exponential(scale, size) β=1/λ [0, +∞) 等待时间
对数正态 rng.lognormal(mean, sigma, size) ln(X)的μ,σ (0, +∞) 收入分布

(2) 正态分布

正态分布是最常见的连续分布,参数 loc 是均值 μ,scale 是标准差 σ。

PYTHON
rng = np.random.default_rng(42)

# Standard normal: mu=0, sigma=1
data = rng.standard_normal(10000)
print(f"Mean: {data.mean():.4f}")   # ≈ 0
print(f"Std:  {data.std():.4f}")    # ≈ 1

# Custom normal: mu=170, sigma=6 (heights in cm)
heights = rng.normal(loc=170, scale=6, size=10000)
print(f"Mean: {heights.mean():.2f} cm")  # ≈ 170
print(f"Std:  {heights.std():.2f} cm")   # ≈ 6
TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

(3) 均匀分布

PYTHON
rng = np.random.default_rng(42)

# Uniform floats in [0, 1)
u = rng.random(5)
print("Uniform [0,1):", u)

# Uniform floats in [a, b)
a, b = 10, 20
u_range = rng.uniform(a, b, size=5)
print(f"Uniform [{a},{b}):", u_range)

# Uniform integers in [low, high)
dice = rng.integers(1, 7, size=5)  # 1~6
print("Dice:", dice)
TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

(4) 二项分布与泊松分布

PYTHON
rng = np.random.default_rng(42)

# Binomial: flip 10 coins, count heads (p=0.5)
heads = rng.binomial(10, 0.5, size=5)
print("Heads out of 10 flips:", heads)
# e.g. [5 7 4 6 3]

# Poisson: average 3 events per interval
events = rng.poisson(lam=3, size=5)
print("Events per interval:", events)
# e.g. [2 4 1 5 3]
TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

▶ 示例

TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

:正态/均匀/二项(难度⭐⭐)

PYTHON
import numpy as np

rng = np.random.default_rng(seed=42)

# Normal distribution: simulate exam scores (mean=75, std=12)
scores = rng.normal(loc=75, scale=12, size=1000)
print(f"Scores - Mean: {scores.mean():.1f}, Std: {scores.std():.1f}")
print(f"Min: {scores.min():.1f}, Max: {scores.max():.1f}")

# Uniform distribution: random arrival times in [0, 60) minutes
arrivals = rng.uniform(0, 60, size=1000)
print(f"\nArrivals - Mean: {arrivals.mean():.1f} min (expect 30)")

# Binomial: 20-question true/false test, p=0.5
correct = rng.binomial(20, 0.5, size=1000)
print(f"\nCorrect answers - Mean: {correct.mean():.1f} (expect 10)")
print(f"Got all 20 right: {(correct == 20).sum()} times")
TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

5. choice / shuffle / permute

(1) 采样函数对比

函数 作用 是否原地修改 返回值
rng.choice(a, size) 从 a 中随机选取 新数组
rng.shuffle(a) 原地打乱顺序 None
rng.permutation(a) 返回打乱后的副本 新数组
rng.permuted(a) 沿指定轴打乱 新数组

(2) choice 详解

PYTHON
rng = np.random.default_rng(42)

# Choose from list
fruits = rng.choice(["apple", "banana", "cherry"], size=5)
print("Random fruits:", fruits)

# Choose without replacement
lottery = rng.choice(range(1, 50), size=6, replace=False)
print("Lottery numbers:", sorted(lottery))

# Choose with weights
weighted = rng.choice(["A", "B", "C"], size=10, p=[0.5, 0.3, 0.2])
print("Weighted choice:", weighted)
TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

(3) shuffle vs permutation

PYTHON
rng = np.random.default_rng(42)

# shuffle: in-place, returns None
a = np.arange(10)
result = rng.shuffle(a)
print("After shuffle, a =", a)    # a is shuffled
print("shuffle returns:", result)  # None

# permutation: returns new array, original unchanged
b = np.arange(10)
c = rng.permutation(b)
print("Original b =", b)  # [0 1 2 3 4 5 6 7 8 9]
print("Permuted c =", c)  # shuffled copy
TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

▶ 示例

TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

:choice/shuffle(难度⭐⭐)

PYTHON
import numpy as np

rng = np.random.default_rng(seed=42)

# Simulate drawing cards
deck = np.arange(52)
hand = rng.choice(deck, size=5, replace=False)
print("Poker hand:", hand)

# Shuffle and deal
deck_copy = np.arange(52)
rng.shuffle(deck_copy)
player1 = deck_copy[:13]
player2 = deck_copy[13:26]
print(f"Player 1 has {len(player1)} cards")

# Weighted sampling: biased coin (70% heads)
flips = rng.choice(["H", "T"], size=100, p=[0.7, 0.3])
heads_count = (flips == "H").sum()
print(f"Heads: {heads_count}/100 (expect ~70)")

# Permutation for train/test split
indices = rng.permutation(100)
train_idx = indices[:80]
test_idx = indices[80:]
print(f"Train: {len(train_idx)}, Test: {len(test_idx)}")
TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

6. 随机种子与可复现

(1) 种子设哪

PYTHON
# ✅ Recommended: seed in default_rng
rng = np.random.default_rng(seed=42)
print(rng.random(3))  # reproducible

# ⚠️ Old style: global seed (affects all code)
# np.random.seed(42)  # NOT recommended
TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

最佳实践:default_rng() 中设置种子,而非使用 np.random.seed()。前者只影响单个 Generator 实例,后者修改全局状态。

(2) 种子与可复现性

PYTHON
# Same seed → same sequence
rng1 = np.random.default_rng(seed=123)
rng2 = np.random.default_rng(seed=123)

print(rng1.integers(1, 100, size=5))
print(rng2.integers(1, 100, size=5))
# Both produce identical output!

# Different seed → different sequence
rng3 = np.random.default_rng(seed=456)
print(rng3.integers(1, 100, size=5))
TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

▶ 示例

TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

:种子/可复现(难度⭐)

PYTHON
import numpy as np

# Demonstrate reproducibility
def simulate_dice(seed, n=10):
    rng = np.random.default_rng(seed=seed)
    return rng.integers(1, 7, size=n)

# Same seed → identical results
a = simulate_dice(seed=42)
b = simulate_dice(seed=42)
print("Seed 42, run 1:", a)
print("Seed 42, run 2:", b)
print("Identical:", np.array_equal(a, b))  # True

# Different seed → different results
c = simulate_dice(seed=99)
print("Seed 99:      ", c)
print("Identical:", np.array_equal(a, c))  # False

# Independent generators don't interfere
rng_a = np.random.default_rng(seed=1)
rng_b = np.random.default_rng(seed=1)
val_a = rng_a.random(3)
rng_a.random(100)  # advance rng_a
val_b = rng_b.random(3)
print("rng_a first 3:", val_a)
print("rng_b first 3:", val_b)
print("Same:", np.array_equal(val_a, val_b))  # True
TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

7. 蒙特卡洛模拟

(1) 蒙特卡洛 vs 解析解

对比项 蒙特卡洛 解析解
思路 大量随机模拟 → 统计频率 数学推导 → 精确公式
精度 随样本量增加,误差 ∝ 1/√N 精确(无随机误差)
适用范围 几乎任何概率问题 仅限可推导的问题
实现难度 低(模拟 + 计数) 高(需数学功底)
速度 需要大量样本才精确 一次计算得结果

(2) 蒙特卡洛模拟流程

100%
graph TB
    A["定义概率问题"] --> B["设计模拟方案"]
    B --> C["生成大量随机样本"]
    C --> D["统计目标事件频率"]
    D --> E["频率 ≈ 概率"]
    E --> F{"精度足够?"}
    F -->|是| G["输出结果"]
    F -->|否| C

    style A fill:#4CAF50,color:#fff
    style B fill:#2196F3,color:#fff
    style C fill:#FF9800,color:#fff
    style D fill:#9C27B0,color:#fff
    style E fill:#E91E63,color:#fff
    style G fill:#4CAF50,color:#fff
TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

(3) 蒙特卡洛估算 π

单位正方形内画一个 1/4 圆,随机撒点,落在圆内的比例 ≈ π/4。

PYTHON
rng = np.random.default_rng(42)
N = 1_000_000

x = rng.random(N)
y = rng.random(N)
inside = (x**2 + y**2) <= 1.0

pi_estimate = 4 * inside.mean()
print(f"Estimated pi: {pi_estimate:.6f}")
print(f"Actual pi:    {3.141593:.6f}")
print(f"Error:        {abs(pi_estimate - 3.141593):.6f}")
TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

▶ 示例

TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

:蒙特卡洛 π(难度⭐⭐⭐)

PYTHON
import numpy as np

rng = np.random.default_rng(seed=42)

print("=== Monte Carlo Estimation of Pi ===\n")

for N in [1000, 10000, 100000, 1000000]:
    x = rng.random(N)
    y = rng.random(N)
    inside = (x**2 + y**2) <= 1.0
    pi_est = 4 * inside.mean()
    error = abs(pi_est - np.pi)
    print(f"N={N:>8,d}  Pi≈{pi_est:.6f}  Error={error:.6f}")

# N=   1,000  Pi≈3.116000  Error=0.025593
# N=  10,000  Pi≈3.139600  Error=0.001993
# N= 100,000  Pi≈3.141880  Error=0.000287
# N=1,000,000  Pi≈3.141268  Error=0.000325
TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

8. PCG64 算法

(1) 为什么 PCG64 优于 MT19937

特性 PCG64 MT19937
周期 2^128 2^19937-1
统计质量 优秀(通过所有测试) 存在已知缺陷
速度 快(~3 ns/样本) 较慢(~4 ns/样本)
状态大小 128 bit 2.5 KB
可预测性 难以预测输出 输出可部分预测

PCG64 是 default_rng() 的默认算法,无需手动指定。

PYTHON
# Explicit PCG64 (same as default)
from numpy.random import PCG64
rng = np.random.default_rng(PCG64(42))

# Use a different BitGenerator if needed
from numpy.random import Philox
rng_philox = np.random.default_rng(Philox(42))
TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

9. 综合示例:蒙特卡洛估计

▶ 示例

TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

:骰子概率 + 股价随机游走 + 生日悖论(难度⭐⭐⭐)

PYTHON
import numpy as np

rng = np.random.default_rng(seed=42)

# ========================================
# Part 1: Dice Probability
# ========================================
print("=== Part 1: Dice Probability ===\n")

# Q: Roll 1000 dice, probability of getting exactly 3 sixes?
N_sim = 100_000
sixes = rng.binomial(1000, 1/6, size=N_sim)
prob_3_sixes = (sixes == 3).mean()
print(f"P(exactly 3 sixes in 1000 rolls) ≈ {prob_3_sixes:.6f}")

# Analytical comparison
from math import comb
p_exact = comb(1000, 3) * (1/6)**3 * (5/6)**997
print(f"Analytical:                        {p_exact:.6f}")

# ========================================
# Part 2: Stock Price Random Walk
# ========================================
print("\n=== Part 2: Stock Price Random Walk ===\n")

# Geometric Brownian Motion
S0 = 100        # initial price
mu = 0.05 / 252  # daily drift (5% annual)
sigma = 0.2 / np.sqrt(252)  # daily volatility (20% annual)
days = 252       # 1 year
n_paths = 5

for i in range(n_paths):
    daily_returns = rng.normal(mu, sigma, size=days)
    price_path = S0 * np.cumprod(1 + daily_returns)
    final_price = price_path[-1]
    print(f"Path {i+1}: Start={S0:.0f} → End={final_price:.2f} "
          f"(Return={((final_price/S0)-1)*100:+.1f}%)")

# ========================================
# Part 3: Birthday Paradox
# ========================================
print("\n=== Part 3: Birthday Paradox ===\n")

# Q: In a room of N people, probability that at least 2 share a birthday?
def birthday_prob(n_people, n_sim=50_000):
    rng_local = np.random.default_rng(42)
    birthdays = rng_local.integers(1, 366, size=(n_sim, n_people))
    has_duplicate = np.array([len(set(row)) < n_people for row in birthdays])
    return has_duplicate.mean()

for n in [10, 23, 30, 40, 50, 70]:
    prob = birthday_prob(n)
    print(f"N={n:>2}: P(shared birthday) ≈ {prob:.3f}")
# N=23 is the famous threshold: ~50% chance!
TEXT 📖 仅展示
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。

❓ 常见问题

Q 为什么用 default_rng 而不是 np.random.rand?
A default_rng() 返回独立 Generator 实例,流式设计互不干扰;np.random.rand() 依赖全局状态,多线程或多次调用时会互相影响。新版 API 还默认使用更高质量的 PCG64 算法。
Q 随机种子应该设在哪?
Adefault_rng(seed=42) 中设置,而非 np.random.seed(42)。前者只影响该 Generator 实例,后者修改全局状态。开发/调试时固定种子保证可复现,生产环境可省略种子获取真随机。
Q 正态分布的 loc 和 scale 参数怎么理解?
A loc 是均值 μ(数据中心位置),scale 是标准差 σ(数据离散程度)。约 68% 的值落在 μ±σ 内,95% 落在 μ±2σ 内。standard_normal() 等价于 normal(loc=0, scale=1)
Q 蒙特卡洛精度与样本量有什么关系?
A 误差 ∝ 1/√N。样本量增加 100 倍,误差只缩小 10 倍。例如 N=10000 时误差约 0.01,N=1000000 时误差约 0.001。需要更高精度只能增加样本量。
Q choice 的权重参数 p 怎么用?
A p 是概率数组,必须与候选数组等长且和为 1。例如 rng.choice(["A","B","C"], p=[0.5,0.3,0.2]) 表示 A 被选中概率 50%,B 30%,C 20%。不设 p 则等概率选取。
Q shuffle 和 permutation 怎么选?
A 需要原地打乱用 shuffle(不额外占用内存,返回 None);需要保留原数组用 permutation(返回打乱后的副本,原数组不变)。多数场景 permutation 更安全。

📖 小节


📝 作业

(1) 硬币概率估计

  1. default_rng(seed=0) 创建 Generator
  2. 模拟 100000 次抛 10 枚硬币,统计每次正面数量(binomial(10, 0.5)
  3. 估算"恰好 5 枚正面"的概率
  4. 与解析值 comb(10,5) * 0.5**10 ≈ 0.246 对比,计算误差

(2) 1000 天股价随机游走

  1. 初始价格 S0=50,日漂移 μ=0.0003,日波动 σ=0.02
  2. rng.normal(mu, sigma, size=1000) 生成日收益率
  3. np.cumprod(1 + returns) 计算价格路径
  4. 绘制/打印第 1、100、500、1000 天的价格
  5. 重复 1000 次模拟,统计最终价格的中位数和均值

(3) 验证大数定律

  1. rng.random() 生成 N 个 [0,1) 均匀随机数
  2. 对 N = 10, 100, 1000, 10000, 100000, 1000000 分别计算样本均值
  3. 打印每个 N 的均值与理论均值 0.5 的偏差
  4. 观察偏差随 N 增大而趋近 0(大数定律)
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏