代码学习记录

整理学习过程中常用的概念、代码和命令。

HTML 结构

HTML 负责描述网页的内容和结构。写页面时先考虑内容之间的关系,再选择合适的标签。

常用语义化标签

<article>
  <header>
    <h2>文章标题</h2>
    <time datetime="2026-08-08">2026-08-08</time>
  </header>
  <p>文章正文。</p>
</article>

标题应该按层级排列,不要只为了字体大小跳过层级。图片需要填写有意义的 alt,纯装饰图片可以使用空的 alt。

CSS 布局

CSS 主要学习盒模型、层叠规则、Flex、Grid 和响应式设计。

盒模型

一个元素由 content、padding、border 和 margin 组成。项目中通常统一设置:

* {
  box-sizing: border-box;
}

Grid 自适应布局

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
}

auto-fit 会根据可用宽度调整列数,minmax 限制每列的最小和最大宽度。

响应式原则

表单与无障碍

每个输入框都应该有对应的 label。键盘用户需要能看见焦点位置,错误提示不能只依靠颜色。

<form>
  <label for="email">邮箱</label>
  <input id="email" name="email" type="email" required>
  <button type="submit">提交</button>
</form>

JavaScript 变量与函数

优先使用 const,确实需要重新赋值时使用 let。函数尽量只完成一件事,并通过参数接收数据。

function calculateTotal(items) {
  return items.reduce((total, item) => {
    return total + item.price * item.quantity;
  }, 0);
}

const total = calculateTotal([
  { price: 12, quantity: 2 },
  { price: 8, quantity: 3 }
]);

数组常用方法

JavaScript 异步操作

网络请求、定时器和文件读取不会立刻完成,需要通过 Promise 处理最终结果。

async function loadData(url) {
  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), 5000);

  try {
    const response = await fetch(url, { signal: controller.signal });
    if (!response.ok) throw new Error(`HTTP ${response.status}`);
    return await response.json();
  } finally {
    clearTimeout(timer);
  }
}

多个互不依赖的任务可以使用 Promise.all 并发执行。任何一个失败都会让 Promise.all 失败;如果需要保留所有结果,可以使用 Promise.allSettled

DOM 与事件

DOM 是浏览器提供的页面对象模型。修改页面前先保存需要的元素引用,避免重复查询。

const list = document.querySelector(".list");

list.addEventListener("click", (event) => {
  const button = event.target.closest("button[data-id]");
  if (!button) return;
  console.log("点击项目:", button.dataset.id);
});

上面的写法叫事件委托。事件统一绑定在父元素上,适合处理动态添加的大量子元素。

Python 类型与数据类

类型注解能让函数的输入和输出更清楚,dataclass 适合表示结构固定的数据。

from dataclasses import dataclass

@dataclass(frozen=True)
class Student:
    name: str
    scores: list[float]

    def average(self) -> float:
        return sum(self.scores) / len(self.scores) if self.scores else 0.0

frozen=True 表示对象创建后不能随意修改,可以减少状态变化造成的问题。

Python 文件和数据处理

读写文本时明确指定编码,并使用 with 自动关闭文件。处理外部数据时要检查字段是否存在、类型是否正确。

import json
from pathlib import Path

def load_config(path: str) -> dict:
    file = Path(path)
    if not file.exists():
        return {}
    with file.open("r", encoding="utf-8") as stream:
        return json.load(stream)

处理数据的步骤

  1. 读取原始数据。
  2. 检查缺失值和重复值。
  3. 统一日期、数字和文本格式。
  4. 计算需要的结果。
  5. 保存结果并记录处理时间。

测试与异常

测试应该覆盖正常输入、边界情况和错误输入。异常信息需要说明发生了什么,而不是简单返回失败。

def divide(a: float, b: float) -> float:
    if b == 0:
        raise ValueError("b cannot be zero")
    return a / b

def test_divide():
    assert divide(10, 2) == 5

Git 工作流

每次提交只包含一类修改。开始工作前创建分支,提交前查看差异,合并前运行测试。

git switch -c feature/example
git status
git diff
git add src/example.py
git commit -m "add example parser"
git rebase main

排查问题

Linux 常用命令

pwd                 # 当前目录
ls -la              # 查看文件
cd /path/to/project # 切换目录
cp source target    # 复制文件
mv old new          # 移动或重命名
grep -R "text" .    # 搜索文本
tail -f app.log     # 持续查看日志

执行修改或删除命令前,先用只读命令确认目录和目标文件。服务出现问题时,依次检查进程、端口、日志和配置。

HTTP 基础

一次 HTTP 请求包含方法、地址、请求头和可选的请求体;响应包含状态码、响应头和响应体。

常见状态码

HTTPS 在 HTTP 外增加 TLS 加密。证书需要匹配域名,并在过期前完成续期。

数据结构与算法

选择数据结构时要考虑读取、插入、删除和查找操作的频率。

def binary_search(nums: list[int], target: int) -> int:
    left, right = 0, len(nums) - 1
    while left <= right:
        middle = (left + right) // 2
        if nums[middle] == target:
            return middle
        if nums[middle] < target:
            left = middle + 1
        else:
            right = middle - 1
    return -1

二分查找要求数据已经排序,时间复杂度为 O(log n)。

数据库

关系型数据库通过表保存数据。主键唯一标识一行,外键描述表之间的关系,索引用额外空间提高查询速度。

CREATE TABLE students (
  id INTEGER PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  created_at TIMESTAMP NOT NULL
);

CREATE INDEX idx_students_name ON students(name);

需要继续学习

学习计划

  1. 完成一个带数据库的小项目。
  2. 为主要功能补充自动化测试。
  3. 学习 Docker 镜像、容器和数据卷。
  4. 学习日志、监控和错误排查。
  5. 继续练习算法题并记录复杂度。