📚 知识大全 · 工具指南

配合博客学习路径使用,遇到陌生概念来这里查。每条词条按「是什么 → 什么时候用 → 怎么用 → 相关词条」组织;从文章跳进来,看完点「返回刚才的文章」就能回去。

⚠️ 安全提醒:教程和博客里不要写真实服务器 IP、SSH 账号、API Key、数据库密码等敏感信息,示例一律用占位符。

工程实践 · 建站与运维(17 条)

AI 与数据实验(15 条)

编程语言 · C / C++(56 条)

编程语言 · C / Java / Python(24 条)

一、网络与建站

IP 地址 IP address

是什么:每台联网设备的“门牌号”,一串数字,比如 1.2.3.4。只有拿到对方的 IP,别人才找得到它。

什么时候用:登录服务器、配域名解析、排查网络时都会用到。注意区分「公网 IP」(外面能访问)和「内网 IP」(只在局域网内有效)。

怎么用
  1. 云服务器:控制台「实例」页看公网 IP。
  2. 登录:ssh root@你的公网IP
  3. 解析:在 DNS 的 A 记录里填这个 IP。
  4. ⚠️ 公网 IP 等于服务器的门牌号,别写进公开博客。

服务器 Server

是什么:一台长期开机、有公网 IP 的电脑,负责收请求、跑程序、回内容。网站、机器人、API、网盘都住在上面。

什么时候用:需要后端(登录、数据库、定时任务)、需要 24 小时在线、或者想把 AI 模型部署给别人用时。

怎么用(选机 → 放行 → 登录 → 装环境)
  1. 云厂商选「包年包月 + 中国大陆」机型(大陆建站要备案;香港/海外不用)。
  2. 重置/设置登录密码,安全组先放行 22。
  3. SSH 登录:ssh root@公网IP
  4. 装基础环境:apt update && apt install nginx php mysql
  5. 最后把域名 A 记录指向它。

网站 Website

是什么:浏览器能访问的内容,本质是「文件」(HTML/CSS/JS),需要互动时再加后端程序和数据库。

什么时候用:博客、作品集、工具站用静态页就够;需要登录/评论/动态内容再上后端。

怎么用(先区分静态还是动态)
  1. 纯展示:写 index.html,推 GitHub Pages / Vercel,免费。
  2. 动态站:买服务器,装 Nginx + PHP + 数据库(如 WordPress)。
  3. 访问方式:域名或 IP 都行,正式用域名 + HTTPS。

域名 Domain

是什么:IP 的好记名字,如 example.com。结构上由「名字 + 后缀」组成,后缀叫顶级域(.com / .icu / .cn),前面还可以加 wwwblog 等子域名。

什么时候用:让别人不用记一串数字;做邮箱、短链接、个人品牌时也需要。

怎么用
  1. 注册商购买(要实名)。
  2. 去 DNS 管理加 A 记录指向服务器。
  3. ping 你的域名 确认解析成功。
  4. 到期续费;备案前别用域名对外建站。

网址 URL

是什么:定位某个资源的完整地址,格式为「协议 + 域名 + 路径」,如 https://example.com/posts/a.html

什么时候用:填站点地址、发链接、配重定向时。

怎么用
  1. 协议:http(明文)→ 尽量用 https(加密)。
  2. 域名:去哪台服务器;路径:服务器上的哪个文件。
  3. 后台「站点地址」记得写完整的 https://域名

DNS / 解析 Domain Name System

是什么:把「域名」翻译成「IP」的分布式通讯录。你在域名服务商那里写的「解析记录」,决定访问域名时去哪个服务器。

什么时候用:把域名指向服务器、配邮箱、做子域名时。

怎么用
  1. 进入域名服务商后台 → DNS 解析/域名解析。
  2. 加 A 记录:主机记录 @(或 www),记录值填公网 IP。
  3. 保存后通常几分钟到几小时生效(全球同步)。
  4. 验证:ping 域名nslookup 域名

DNS 记录类型 DNS Records

是什么:同一条域名可以配置多种“指令”,不同类型管不同的事。

什么时候用:建站用 A,别名用 CNAME,邮箱用 MX,验证归属用 TXT。

怎么用(对照表)
  1. A:指向 IPv4,建站必配,值填公网 IP。
  2. AAAA:指向 IPv6(可选)。
  3. CNAME:指向另一个域名,如 www → 主域名。
  4. MX:邮件接收服务器;TXT:域名验证 / 邮件 SPF。

端口 Port

是什么:一台服务器有多个“门”,每个服务占一个门。比如网页走 80/443,SSH 走 22,数据库默认 3306。

什么时候用:配置防火墙、Nginx 监听、访问数据库/API 时都要写对端口。

怎么用
  1. 对外只开必要端口:22、80、443。
  2. 3306 等数据库端口不要对公网开放。
  3. 改监听端口后记得同步改安全组,否则外面连不上。

SSH Secure Shell

是什么:远程安全登录服务器的协议,默认端口 22。有两种登录方式:密码 和 密钥(更安全、免密)。

什么时候用:管理服务器、往服务器传代码、GitHub 免密推送。

怎么用
  1. 密码登录:ssh root@公网IP,回车输密码。
  2. 生成密钥:ssh-keygen -t ed25519(一路回车)。
  3. 公钥加服务器:ssh-copy-id root@公网IP;加 GitHub:Settings → SSH keys。
  4. 测试 GitHub:ssh -T git@github.com

防火墙 / 安全组 Firewall

是什么:控制“外面能不能访问某个端口”的门卫。云厂商的叫「安全组」,服务器系统里还可以用 ufw/iptables。

什么时候用:新服务器第一件事就是放行 22;建站再加 80/443。

怎么用
  1. 云控制台 → 安全组 → 入方向:允许 TCP 22/80/443,来源 0.0.0.0/0
  2. 系统内(可选):ufw allow 22/tcpufw allow 80/tcpufw enable
  3. 原则:默认全关,只开要用的;3306 绝不开。

ICP 备案 ICP Filing

是什么:中国大陆机房里的网站,上线前要在工信部登记网站主体(个人或企业)和内容。规则是「谁接入谁备案」——服务器在哪家云,就在哪家备案。

什么时候用:服务器在大陆、要用域名提供网站服务时。香港/海外服务器不需要。

怎么用
  1. 域名先完成实名认证。
  2. 云厂商控制台 → ICP 备案 → 填主体/网站信息 → 证件 + 人脸核验。
  3. 云厂商初审 → 管局终审(1~20 个工作日)。
  4. 通过后把备案号挂在页脚,并链接 beian.miit.gov.cn
  5. ⚠️ 审核期间别用域名开放网站,容易被退回。

HTTPS / SSL 证书 Certificate

是什么:把网站通信加密的“锁”。装了证书,地址变 https://,别人窃听不到内容,浏览器也不会提示“不安全”。

什么时候用:任何正式上线的网站都要用;有登录、支付、表单时尤其重要。

怎么用(Nginx + Let's Encrypt 免费方案)
  1. 装工具:apt install certbot python3-certbot-nginx
  2. 执行:certbot --nginx -d 你的域名 -d www.你的域名
  3. 按提示选邮箱、同意条款;certbot 自动改配置并续期。
  4. 完成后强制跳转:选 --redirect 或手动加 301。

Nginx / 反向代理 Web Server

是什么:最常用的 Web 服务器:接收浏览器请求,把静态文件直接返回,把 PHP/后端请求转给对应程序(这就是“反向代理”)。

什么时候用:几乎所有 Linux 建站都会用到;还能做 HTTPS、负载均衡、缓存。

怎么用
  1. 安装:apt install nginx
  2. 写站点配置:server_name 域名root 网站目录、PHP 转发到 php-fpm.sock
  3. 测试:nginx -t;生效:systemctl reload nginx
  4. 配置目录:/etc/nginx/sites-available + 软链到 sites-enabled

WordPress CMS

是什么:最流行的开源建站程序(PHP 写的),自带可视化后台,发文、换主题、装插件都在网页里点。

什么时候用:不想手写页面、想要后台管理文章和评论时,博客/作品集/企业站都能用。

怎么用
  1. 下载并解压到网站目录(如 /var/www/blog),目录属主设为 www-data
  2. 提前建好数据库(见「数据库」词条)。
  3. 浏览器访问域名,按向导填数据库信息、设管理员账号。
  4. 后台 /wp-admin 写文章、改主题;及时更新版本和插件。

PHP PHP

是什么:一种后端语言,WordPress 就是用它写的。Nginx 本身不处理 PHP,需要交给 php-fpm 处理。

什么时候用:跑 WordPress / Typecho 等 PHP 程序时。

怎么用
  1. 安装:apt install php8.1-fpm php8.1-mysql(按需加 gd/curl/xml 等扩展)。
  2. Nginx 配置里把 .php 请求转发给 php8.1-fpm.sock
  3. 重启:systemctl reload nginx

数据库 Database

是什么:程序持久化存数据的仓库。博客用 MySQL/MariaDB 存文章、用户、评论;大数据/灵活结构也会用 MongoDB。

什么时候用:WordPress 安装时、任何需要登录/存储的程序里。

怎么用(MySQL/MariaDB)
  1. 进入:sudo mysql
  2. 建库 + 建用户 + 授权:CREATE DATABASE blog ...; CREATE USER ...; GRANT ...; FLUSH PRIVILEGES;
  3. 程序填库名/用户名/密码,主机 localhost
  4. 备份:mysqldump blog > blog.sql;恢复:mysql blog < blog.sql

免费托管 Static Hosting

是什么:不买服务器也能放网站的云服务,如 GitHub Pages、Vercel、Netlify。适合静态站(无后端)。

什么时候用:作品集、文档站、纯展示页;想快速上线、省维护时。

怎么用
  1. 把网站文件夹推到一个 GitHub 仓库。
  2. Vercel/Netlify 登录 → Import 这个仓库,自动部署。
  3. 平台自动给 HTTPS 网址;设置里可绑定自己的域名。
  4. 有数据库/登录/API 需求时再换服务器。

二、AI 与大模型

LLM 大语言模型 Large Language Model

是什么:用海量文本训练出来的“文字大脑”,能理解问题并生成回答。常见的有 GPT、Claude、DeepSeek 等,以及 Llama、Qwen 等开源模型。

什么时候用:写文案、答疑、写代码、做助手。要“自己动”就升级成 Agent(加工具)。

怎么用(两条路)
  1. 云 API:注册 → 拿 Key → 用官方 SDK 调用(省事但按量计费)。
  2. 本地部署:用 Ollama 等跑开源模型(免费但要显卡/内存)。
  3. 调用本质:发一列 messages(system/user),取回 content

Token Token

是什么:模型处理文本的最小单位。中文大致 1 个字 ≈ 1~2 Token;它决定两件事:计费和能记住的长度。

什么时候用:估算成本、判断“怎么又超出上下文了”时。

怎么用
  1. 计费看「输入 + 输出」两边,长对话/长文档成本高。
  2. 上下文满了:精简输入、先让模型总结历史,或用 RAG 只取相关段。
  3. 选模型前看它的上下文窗口(几千~几十万 Token)。

API 与 API Key API

是什么:API 是“接口”,让程序按固定格式请求模型;API Key 是证明“你是谁”的钥匙,直接关系账户里的钱。

什么时候用:程序要调云端模型、或自己部署模型给别人调用时。

怎么用
  1. 环境变量存 Key:export OPENAI_API_KEY="sk-..."(Windows:$env:OPENAI_API_KEY="...")。
  2. 代码:from openai import OpenAI; client.chat.completions.create(...)
  3. 安全:Key 不进 Git、不贴网页、不截图外发;开额度限制。
  4. 本地模型也走同一套接口,只是换个 base_url(见 OpenAI 兼容 API)。

Prompt 提示词 Prompt

是什么:你发给模型的指令。同样的模型,指令写得好不好,结果天差地别。研究怎么把指令写好就叫 Prompt 工程。

什么时候用:每次调用都在写 Prompt;复杂任务尤其需要结构化。

怎么用(四件套模板)
  1. 角色:你是一位……
  2. 任务:请帮我……
  3. 要求:用大白话 / 不超 200 字 / 分点列出。
  4. 示例:给一个输入输出的样例,模型会照着学。

上下文窗口 Context Window

是什么:模型一次能“同时看到”的内容上限(按 Token 算)。超过部分它根本看不到。

什么时候用:长文档、长对话、多轮 Agent 循环时最容易“爆上下文”。

怎么用
  1. 对话太长:定期让模型“总结前面聊了什么”再继续。
  2. 文档太长:别整篇塞,用 RAG 只取相关段落。
  3. Agent 循环:每轮只保留最近几步 + 全局任务目标。

RAG 检索增强生成 Retrieval-Augmented Generation

是什么:让模型“带资料答题”:先把你的文档变成可检索的库,提问时先查出相关片段,再连问题一起交给模型。

什么时候用:想让 AI 回答你私有的 PDF/笔记/文档,而不是瞎编时。

怎么用
  1. 把文档切成小段(几百字一段)。
  2. 每段用 Embedding 转成向量存进向量库。
  3. 提问 → 检索最相近的 TopK 段 → 拼进 Prompt → 让模型基于资料回答。
  4. 资料更新后重新切片入库即可。

Embedding 向量 Embedding

是什么:把文字变成一串数字(向量)。语义越接近的文字,向量距离越近——这是“机器能算相似度”的基础。

什么时候用:做相似搜索、RAG 资料库、去重、推荐时。

怎么用
  1. 用 Embedding API 把文本转成向量(如 1536 维数组)。
  2. 存进向量库(如 Chroma、pgvector、MongoDB Atlas)。
  3. 查询时把问题也转成向量,按距离取最近几条。

Agent 智能体 AI Agent

是什么:能自己“规划 → 调工具 → 看结果 → 继续做”直到完成任务的小程序,而不是一问一答的聊天框。

什么时候用:任务需要多步、需要查数据/执行代码/操作文件时。

怎么用
  1. 定义工具:每个工具是一个函数(搜索、查数据库、执行代码…)。
  2. 写循环:模型选择工具 → 程序执行 → 结果作为消息喂回去 → 判断完成。
  3. 控制权:关键操作(删数据、花钱、发消息)加人工确认。
  4. 从最小 Demo 开始:1 个工具 + 明确目标,跑通再加。

Function Calling 工具调用 Function Calling

是什么:模型不自己执行操作,而是输出“我要调用函数 X,参数是 Y”,由你的程序真正执行——这是 Agent 的“手”。

什么时候用:让模型查天气、算数、读文件、发请求时。

怎么用
  1. 请求时声明工具(名称、参数 JSON Schema、说明)。
  2. 解析回复中的 tool_calls
  3. 执行函数,把结果作为 role:"tool" 消息返回。
  4. 模型基于结果继续回答或调用下一个工具。

微调 Fine-tuning

是什么:用你自己的数据继续训练模型,让它更懂你的语气、格式或业务规则。比 Prompt 重,属于“深度定制”。

什么时候用:Prompt/RAG 都试过仍不够,且你有成对的数据(问题+标准回答)时。

怎么用
  1. 先确认:大概率不需要微调,Prompt 最省事。
  2. 准备数据:JSONL,每行是 role 对话。
  3. 云平台一键微调,或本地用 LLaMA-Factory 等框架。
  4. 评估效果:拿没见过的问题测,别只看训练集。

量化 Quantization

是什么:把模型的数字精度降低(如 16 位 → 4/8 位),体积和显存占用大幅变小,质量略降。这是本地跑大模型的“魔法”。

什么时候用:显存/内存不够、想在个人电脑或小服务器上跑模型时。

怎么用
  1. 按显存选级别:Q4_K_M/Q5 家用推荐,Q8 更准但更大。
  2. Ollama 拉模型默认就是量化版:ollama run 模型名
  3. 还是跑不动 → 换更小参数的模型(7B → 3B/1.5B)。

推理 Inference

是什么:模型“生成回答”的运行过程,主要吃显卡显存(VRAM)。部署模型本质上就是“起一个推理服务”。

什么时候用:本地部署选工具、估算能不能跑、排查“怎么这么慢”时。

怎么用
  1. 先看显卡显存(nvidia-smi),决定能跑多大模型。
  2. 自己试:Ollama;服务多人:vLLM(吞吐高)。
  3. 慢/爆显存:降并发、升量化、换小模型、换更快硬盘。

Ollama Local Runner

是什么:一条命令在本地跑开源模型的小工具,会自动下载并管理量化模型,还自带一个 OpenAI 兼容接口,最适合入门本地部署。

什么时候用:想在个人电脑上免费跑模型、研究本地部署、不想把数据发到云端时。

怎么用
  1. 安装(官网下载/一行脚本)。
  2. 跑起来:ollama run llama3(或 qwen3 等)。
  3. 看列表:ollama list;删除:ollama rm 模型
  4. 代码接入:base_url="http://localhost:11434/v1",api_key 随意。

vLLM Inference Engine

是什么:面向高并发的推理引擎,显存利用率和吞吐比裸跑高很多,适合放在服务器上服务多个用户。

什么时候用:有 GPU 服务器、多人同时调用、追求吞吐和稳定时。

怎么用
  1. 安装:pip install vllm
  2. 启动:vllm serve Qwen/Qwen2.5-7B-Instruct
  3. 默认开在 http://0.0.0.0:8000/v1,OpenAI 格式直接调。
  4. 按显存调并发:--max-num-seqs 等参数。

OpenAI 兼容 API Compatible Endpoint

是什么:一套被广泛使用的调用格式。云厂商、Ollama、vLLM 都提供兼容接口,所以换模型常常只改一行 base_url

什么时候用:在云 API 和本地模型之间切换、或想“代码写一次到处跑”时。

怎么用
  1. base_url:云端填官方地址,本地填 http://localhost:11434/v1
  2. model:写服务端支持的模型名。
  3. api_key:云端填真 Key;本地一般随便填。
  4. messages 结构不变,代码无需大改。

三、编程语言(C / C++)

编译与链接 Compile & Link

是什么:源代码变成可执行文件的两个阶段:编译把每个 .cpp 单独翻译成目标文件,链接把所有目标文件和库拼成可执行文件。

什么时候用:报错时先分清是编译错误还是链接错误——两类错误的排查方向完全不同。

怎么用
  1. g++ -std=c++17 -o app main.cpp 一条命令里其实自动做了编译 + 链接。
  2. 编译期只检查“声明”是否可见;链接期才检查“定义”是否存在。
  3. 看到 undefined reference 就是链接错误:函数声明了但没实现,或源文件没参与编译。

编译选项 Compiler flags

是什么:给编译器的开关,最常用的是 C++ 标准版本和警告等级。

什么时候用:每天都在用;写代码时把警告全开,能提前发现一半的低级错误。

怎么用
  1. -std=c++17 指定标准版本;课本里用到结构化绑定、if 初始化就必须 C++17。
  2. -Wall -Wextra 打开大部分警告;-Wpedantic 拒绝非标准写法。
  3. -g 保留调试信息,-O0 关优化,配合调试器使用。
  4. -fsanitize=address,undefined 打开内存与未定义行为检测(见 Sanitizer)。

头文件与 #include Header

是什么:存放声明(函数原型、类定义、模板)的文件,用 #include 在编译前原样展开。

什么时候用:多文件工程里区分“对外暴露的声明”和“内部实现”时。

怎么用
  1. 头文件放声明 + #pragma once(或 include guard)防止重复包含。
  2. 模板、inline 函数、constexpr 函数的定义要放头文件,否则链接不到。
  3. #include <vector> 用尖括号找系统目录;#include "util.h" 用引号先找当前目录。

命名空间 Namespace

是什么:给名字划分地盘,避免不同库里的同名函数/类撞车。

什么时候用:自己写库、或把代码拆成多个模块时。

怎么用
  1. namespace math { int add(int, int); } 定义,math::add(1, 2) 调用。
  2. 不要在头文件里写 using namespace std;——会把污染带给所有引用者。
  3. 匿名命名空间可以用来把函数限制在本文件内。

单一定义规则(ODR) One Definition Rule

是什么:同一个实体在整个程序里只能有一份定义;inline 函数、模板、类定义属于例外(可以多份但必须完全一致)。

什么时候用:遇到“重复定义 / 符号重定义”链接错误时。

怎么用
  1. 函数定义放 .cpp:放头文件会被多个 .cpp 各定义一次,直接链接错误。
  2. 想放头文件就加 inline(模板和类内成员函数天然满足)。
  3. 全局变量定义放 .cpp,头文件里用 extern 声明。

输入输出流 iostream

是什么:C++ 的输入输出机制:std::cin 读、std::cout 写,用 <<>> 连接数据。

什么时候用:所有需要读入数据、输出结果的程序。

怎么用
  1. std::cout << a << '\n'; 不会自动加空格或换行,分隔符要自己写。
  2. std::cin >> x 跳过空白;读整行用 std::getline,两者混用前先 std::cin.ignore()
  3. 算法题开头加 std::ios::sync_with_stdio(false); std::cin.tie(nullptr); 提速。

变量初始化 Initialization

是什么:变量在诞生时有没有被赋值。C++ 不初始化就是“里面是垃圾值”,读它是未定义行为。

什么时候用:每次声明变量时——默认用花括号 {} 最省心。

怎么用
  1. int a; 未初始化,读它是 UB;int a{}; 一定是 0。
  2. int n{3.14}; 会编译报错(禁止窄化),int n = 3.14; 会静默丢小数。
  3. std::vector<int> v(5) 是 5 个 0,v{5} 是 1 个 5。

整数溢出 Integer overflow

是什么:数值超出类型能表示的范围。C++ 里有符号整数溢出是未定义行为(不是“回绕”),无符号才回绕。

什么时候用:做累加、乘法、下标计算时,只要可能超过 21 亿就要警觉。

怎么用
  1. 不确定就用 long long(64 位,约 9×10^18)。
  2. 判断是否溢出要用更宽的类型先算再比:long long s = a + b; 再和 int 边界比。
  3. 字面量也参与运算:1 << 31 是 UB,写 1LL << 31

类型转换 Type casting

是什么:把一种类型转成另一种。C++ 提供四种具名转换,比 C 风格 (int)x 更明确。

什么时候用:整数除法想得到小数、指针类型互转、去掉 const 等场景。

怎么用
  1. static_cast<double>(a) / b:最常见,编译期检查。
  2. dynamic_cast 用于多态向下转换(运行期检查);const_cast 只改 const;reinterpret_cast 最危险。
  3. 整数相除先转双精度,否则 5 / 2 得 2。

引用 Reference

是什么:变量的别名,必须在定义时绑定,之后不能改绑;不存在空引用。

什么时候用:函数参数想“零拷贝又只读”用 const T&;要写回调用方的变量用 T&

怎么用
  1. const std::vector<int>& v 是最高频的参数写法:不拷贝、不会改。
  2. 不要返回局部变量的引用(悬垂引用 = 未定义行为)。
  3. 引用 vs 指针:指针是“存地址的变量”(可为空、可改指向、可做算术),引用只是别名。

指针 Pointer

是什么:存放内存地址的变量,解引用(*p)就能读写那块内存。

什么时候用:需要表示“可能没有”、需要指针运算、需要和 C 接口打交道时。

怎么用
  1. int* p = &a; 取地址,*p = 5; 改写;p->member 访问成员。
  2. 空指针统一用 nullptr,不要用 NULL 或 0。
  3. 现代 C++ 里裸指针只用来“观察”,所有权交给智能指针(见 RAII)。

const 正确性 const correctness

是什么:用 const 表达“这里不该改”。它既是给编译器的约束,也是给调用方的承诺。

什么时候用:参数、成员函数、指针/引用组合时都要想一遍。

怎么用
  1. 四种组合:const int* p(不能改值)、int* const p(不能改指向)、const int* const p(都不能)、int* p(都能)。
  2. 成员函数加 const(int size() const)表示不修改对象,const 对象只能调用这类函数。
  3. 看到 const T& 立刻理解为“只读且不拷贝”。

栈与堆 Stack & Heap

是什么:栈上对象随作用域自动创建和销毁;堆上对象要手动 new/delete(或用智能指针接管)。

什么时候用:决定“这个对象该放栈还是堆”是 C++ 的基本判断。

怎么用
  1. 默认放栈:Point p{1, 2}; 离开作用域自动析构,零额外开销。
  2. 生命周期要超出作用域、或对象很大、或需要多态时,才放堆:auto p = std::make_unique<Shape>();
  3. 栈空间有限(通常几 MB):大数组和深递归要留意栈溢出。

对象生存期 Object lifetime

是什么:对象从构造完成到析构开始之间的时间;离开作用域、delete、容器清空都会结束生存期。

什么时候用:排查“用了已经销毁的对象”(悬垂引用/指针)时。

怎么用
  1. 栈对象:离开花括号自动销毁。
  2. 堆对象:delete 或智能指针释放时销毁。
  3. 临时对象:所在表达式结束就销毁——不要返回局部变量的引用或指针。

RAII Resource Acquisition Is Initialization

是什么:把资源的申请放在构造函数、释放放在析构函数:对象活着资源就在,对象销毁资源就还。

什么时候用:管理内存、文件、锁、socket 等任何“用完要还”的东西。

怎么用
  1. std::vector/std::string 代替裸数组/char*。
  2. std::unique_ptr 接管 new 出来的对象。
  3. 异常抛出时析构函数照样被调用,所以 RAII 天然异常安全。

智能指针 Smart pointer

是什么:用对象封装裸指针,离开作用域自动 deleteunique_ptr 独占、shared_ptr 共享计数、weak_ptr 不增加计数。

什么时候用:需要堆对象时的默认选择;只有“观察”用途才用裸指针。

怎么用
  1. auto p = std::make_unique<T>(args); 创建,独占所有权,不能拷贝。
  2. auto p = std::make_shared<T>(); 共享,use_count() 查看引用计数。
  3. std::move(p) 转移 unique_ptr 的所有权;用完记得置空或离开作用域。

类与对象 Class & Object

是什么:类是“数据 + 操作数据的方法”打包成的类型;对象是它的实例。C++ 里 struct 和 class 只差默认访问权限。

什么时候用:把一组相关的数据和函数组织在一起时。

怎么用
  1. 成员访问:对象用 .,指针用 ->
  2. 类内可以给成员默认值:double x = 0.0;
  3. 成员函数加 const 表示不修改对象:double dist() const;

构造与析构 Constructor & Destructor

是什么:构造函数把对象初始化到位;析构函数在对象销毁时收尾(释放资源)。

什么时候用:类里需要初始化成员、申请/释放资源时。

怎么用
  1. 初始化列表才是真初始化:Buffer(std::size_t n) : data_(n, 0), size_(n) {}()
  2. 单参数构造函数加 explicit,防止隐式转换。
  3. 多态基类的析构函数必须是 virtual,否则 delete 基类指针不会调用派生类析构。

拷贝控制(零法则与五法则) Rule of Zero / Five

是什么:编译器会自动生成拷贝构造、拷贝赋值、析构等;一旦类里自己管理了裸资源,就得自己写全套。

什么时候用:类里有裸指针/裸数组时;其它情况优先用零法则。

怎么用
  1. 零法则:成员都是 vector/string/智能指针这类“自己管好自己”的类型,什么都不用写。
  2. 五法则:析构、拷贝构造、拷贝赋值、移动构造、移动赋值——需要写一个通常就要写五个。
  3. 拷贝赋值三件事:处理自赋值、先分配后释放、返回 *this

运算符重载 Operator overloading

是什么:让自定义类型支持 +<[]<< 等运算符。

什么时候用:希望自己的类型能直接排序、能像容器一样用下标、能直接打印时。

怎么用
  1. bool operator<(const T& o) const 之后就能直接 std::sort 和放进 set/map。
  2. 比较器必须是严格弱序:相等时返回 false,写成 <= 会让 sort 行为未定义。
  3. = [] () -> 必须是成员函数;<< 输出运算符写成自由函数(左操作数是 ostream)。

继承与多态 Inheritance & Polymorphism

是什么:派生类继承基类接口;只有虚函数才是运行期动态绑定(按实际对象类型调用)。

什么时候用:需要通过基类指针/引用统一处理多种派生类型时。

怎么用
  1. 基类写 virtual double area() const = 0;(纯虚),派生类写 override 让编译器检查签名。
  2. 多态必须通过指针或引用使用;按值传基类会发生“对象切片”,多态信息全丢。
  3. 多态基类必须有虚析构,否则 delete 基类指针时派生类资源泄漏。

模板 Template

是什么:把类型当参数:一份代码,编译器按调用处的类型生成多份具体实现。

什么时候用:需要写“对所有类型都成立”的函数或容器时(顺序表、栈、最大值……)。

怎么用
  1. template <typename T> T maxOf(T a, T b); 调用 maxOf(3, 5) 自动生成 int 版本。
  2. 模板的定义要放头文件(或调用点之前),否则链接不到实例化结果。
  3. 模板不是运行时多态:它在编译期展开,所以没有虚函数开销。

STL Standard Template Library

是什么:C++ 标准库的核心部分:容器 + 迭代器 + 算法,三者通过迭代器解耦。

什么时候用:几乎所有 C++ 程序。选对容器往往直接决定程序快不快。

怎么用
  1. 容器:vector(动态数组)、map/set(有序关联)、unordered_map(哈希)、priority_queue(堆)。
  2. 算法:std::sortfindcount_iflower_bound 都接收迭代器区间(左闭右开)。
  3. 范围 for 是迭代器循环的语法糖:for (const auto& x : v)

vector std::vector

是什么:动态数组:连续内存、可自动扩容、支持随机访问 O(1)。

什么时候用:顺序存储的首选容器;读多写少、需要按下标访问时最合适。

怎么用
  1. v.push_back(x) 追加;v.size() 元素个数;v.capacity() 当前容量。
  2. 已知规模先 v.reserve(n),避免反复扩容搬元素。
  3. 扩容会让所有迭代器、指针、引用失效(见迭代器失效)。

map / set Associative containers

是什么:有序关联容器,底层红黑树:set 是“只有键的集合”,map 是“键→值”的字典,都自动排序、去重。

什么时候用:需要按键有序遍历、需要 O(log n) 查找时。

怎么用
  1. m[key] 在键不存在时会插入默认值——只想查询用 count()find()
  2. 统计频率的经典写法:while (std::cin >> w) { ++freq[w]; }
  3. 需要平均 O(1) 且不要求顺序时换 unordered_map / unordered_set

迭代器 Iterator

是什么:容器元素的“通用指针”:begin() 指向第一个元素,end() 指向最后一个元素的下一位(左闭右开)。

什么时候用:遍历容器、把区间交给算法时。

怎么用
  1. *it 取元素、++it 前进、it->成员 访问成员。
  2. end() 不指向元素,不能解引用。
  3. 习惯写前置 ++it:对自定义类型少一次临时对象。

迭代器失效 Iterator invalidation

是什么:容器结构改变(扩容、插入、删除)后,原来的迭代器/指针/引用可能指向已释放的内存。

什么时候用:在循环里删除或插入元素时——这是最经典的未定义行为来源。

怎么用
  1. vector 扩容后所有迭代器失效;erase 之后的迭代器失效。
  2. 正确写法:it = v.erase(it); 接住返回值,只有没删除时才 ++it
  3. 循环体要改容器结构就不要用范围 for,改用显式迭代器循环。

优先队列 std::priority_queue

是什么:堆结构的适配器:top() 取最值 O(1),插入/删除 O(log n)。默认是大顶堆(和 Java 默认相反)。

什么时候用:需要反复取最大值/最小值时,比如 Top K、Dijkstra。

怎么用
  1. std::priority_queue<int> pq; 大顶堆,pq.top() 是最大值。
  2. 小顶堆要写全:std::priority_queue<int, std::vector<int>, std::greater<int>>
  3. 没有 clear() 也没有迭代器,清空只能逐个 pop 或重新赋值。

栈与队列 Stack & Queue

是什么:两种受限的线性结构:栈后进先出(LIFO),队列先进先出(FIFO)。

什么时候用:表达式求值、括号匹配、DFS(栈)、BFS(队列)、任务排队。

怎么用
  1. std::stack<int>:push / pop / top。
  2. std::queue<int>:push / pop / front / back。
  3. 底层默认用 deque,接口被裁剪成只能在一端操作。

链表 Linked list

是什么:节点通过指针串起来的线性结构:插入删除 O(1)(已知位置),随机访问 O(n)。

什么时候用:频繁在已知位置增删,且不想搬移元素时。

怎么用
  1. 裸指针版要注意三件事:删除维护 prev、表头是特例、析构必须遍历释放全部节点。
  2. 现代写法用 std::unique_ptr<Node> next,析构自动递归释放,不用手写 delete。
  3. 默认拷贝会复制头指针导致双重释放:禁止拷贝或自己写深拷贝。

STL 算法 STL algorithms

是什么:一组以迭代器区间为参数的通用算法:排序、查找、计数、去重、变换……

什么时候用:能用算法库就别手写循环:短、快、不易错。

怎么用
  1. std::sort(v.begin(), v.end(), cmp);
  2. std::count_if(v.begin(), v.end(), pred); 统计满足条件的个数。
  3. 删除元素用 erase-remove 惯用法或 erase 返回值;二分用 lower_bound / upper_bound。

lambda 表达式 Lambda

是什么:就地定义的匿名函数:[](int x) { return x > 0; },可以捕获外部变量。

什么时候用:给算法传比较器/判断条件,或写一次性的小函数时。

怎么用
  1. [&] 按引用捕获、[=] 按值捕获、[x] 只捕获 x。
  2. 排序比较器:[](const auto& a, const auto& b) { return a.score > b.score; }
  3. 递归 lambda 需要把自己当参数传进去(auto&& self)。

auto Type inference

是什么:让编译器从初始化表达式推导类型。不是弱类型:推导结果在编译期就确定了。

什么时候用:类型名又长又啰嗦时(迭代器、结构化绑定)。

怎么用
  1. auto it = m.begin(); 比手写 std::map<std::string,int>::iterator 清爽。
  2. 想改元素用 auto&,只读用 const auto&,别漏 &。
  3. 类型不明显时别用 auto——auto x = compute(); 会让人读不懂。

结构化绑定 Structured bindings

是什么:把 pair/tuple/结构体一次解包成多个变量:auto [a, b] = p;(C++17)。

什么时候用:遍历 map、返回多个值的函数结果时。

怎么用
  1. for (const auto& [key, value] : m) { ... } 是遍历 map 的最舒服写法。
  2. 配合 if 初始化:if (auto it = m.find(k); it != m.end()) { ... }
  3. 需要 C++17:g++ -std=c++17

constexpr Compile-time constant

是什么:要求“编译期就能算出来”的常量与函数:能用在数组长度、模板参数、static_assert 里。

什么时候用:希望把计算提前到编译期、或需要真正的常量表达式时。

怎么用
  1. constexpr int square(int x) { return x * x; } 输入是编译期常量就编译期算完。
  2. static_assert(square(5) == 25); 编译期断言,不满足直接编译失败。
  3. 和 const 的区别:const 只保证“运行期不许改”,constexpr 保证“编译期已知”。

现代 C++ Modern C++

是什么:C++11 之后的一系列改进:auto、范围 for、智能指针、lambda、constexpr、结构化绑定、移动语义……

什么时候用:新写代码都应该用现代写法,别停留在“带类的 C”。

怎么用
  1. 优先用标准库容器和智能指针,少写裸数组和裸 new。
  2. nullptr 代替 NULL,用 enum class 代替裸枚举,用 using 代替 typedef。
  3. 编译加 -std=c++17(或更高),别用十几年前的默认标准。

异常处理 Exception

是什么:用 throw 抛错、try/catch 捕获,把错误从发生的地方传到能处理的地方。

什么时候用:函数无法完成承诺(除零、越界、文件打不开)时;而不是用来控制正常流程。

怎么用
  1. throw std::invalid_argument("divide by zero");
  2. 按 const 引用捕获:catch (const std::exception& e) { std::cout << e.what(); }
  3. 抛异常时栈展开会调用局部对象析构——RAII 写对就不会泄漏。

时间复杂度 Time complexity

是什么:用 O(...) 描述数据量增大时运行时间的增长量级,是选算法和选容器的第一依据。

什么时候用:看数据范围选算法、判断会不会超时。

怎么用
  1. 数据规模对照:n≤20 可以 O(2ⁿ);n≤500 可以 O(n³);n≤5000 可以 O(n²);n≤10⁶ 只能 O(n log n) 或 O(n)。
  2. vector 随机访问 O(1)、map 查找 O(log n)、unordered_map 平均 O(1)、priority_queue 取堆顶 O(1)。
  3. 排序都是 O(n log n) 起步;二分、哈希、双指针常能把 O(n²) 降到 O(n log n) 或 O(n)。

Sanitizer(内存检测) AddressSanitizer / UBSan

是什么:编译期插入检查的运行时工具,能直接报出越界、释放后使用、双重释放、整数溢出等问题。

什么时候用:调试阶段必开;写数据结构、指针相关的代码尤其重要。

怎么用
  1. 编译:g++ -std=c++17 -g -fsanitize=address,undefined -o app app.cpp
  2. 运行程序时若触发问题,会打印错误类型和具体行号后中止。
  3. 只在调试期用;发布版本关掉(慢、占内存)。

调试器(GDB) GNU Debugger

是什么:能下断点、单步执行、查看变量和调用栈的命令行调试器。

什么时候用:程序崩溃(段错误)或结果不对,靠打印排查太慢时。

怎么用
  1. 编译要带调试信息:g++ -std=c++17 -g -O0 -o app app.cpp
  2. 常用命令:break(下断点)、runnext/stepprintbt(看调用栈)、continuequit
  3. 崩溃后先 bt 看调用栈,再 print 关键变量,比从头读代码快得多。

CMake Build system

是什么:用配置文件描述“源文件 + 编译选项 + 目标”,一条命令完成多文件工程的构建。

什么时候用:工程超过一个源文件,或者想把编译选项、sanitizer 开关统一管理时。

怎么用
  1. CMakeLists.txtadd_executable(app util.cpp main.cpp) + target_compile_options
  2. 构建三步:cmake -S . -B buildcmake --build build → 运行。
  3. build/ 是生成物,记得写进 .gitignore

单元测试 Unit test

是什么:给代码写的自动检查:一条命令跑完所有用例,立刻知道有没有改坏。

什么时候用:改了代码不敢确认没影响时;写数据结构时配合随机对拍尤其有效。

怎么用
  1. 最小骨架:注册用例 + 逐个运行 + 统计失败(失败返回非 0 退出码)。
  2. 断言用 assert 或测试库的 EXPECT_EQ / ASSERT_THROW。
  3. 随机对拍:固定随机种子,把同一批随机输入喂给自己的实现和标准库实现,逐项比较。

二叉树与二叉搜索树 Binary tree / BST

是什么:每个节点最多两个孩子的结构;BST 额外保证左子树全部小于根、右子树全部大于根,中序遍历即升序。

什么时候用:需要有序且能快速查找/插入时(std::map、std::set 的底层就是平衡 BST)。

怎么用
  1. 节点用 std::unique_ptr<Node> 管理左右孩子,析构自动释放。
  2. 插入:小于往左、大于往右、相等忽略;中序遍历输出有序序列。
  3. 裸 BST 在插入有序数据时会退化成链表(O(n)),需要平衡结构才能保证 O(log n)。

图的存储与遍历 Graph

是什么:点和边组成的结构;最常用的存储是邻接表 vector<vector<int>>

什么时候用:连通性、最短路、拓扑序、成环判断等问题。

怎么用
  1. 建图:读一条边 u vg[u].push_back(v); g[v].push_back(u);(有向图只存一边)。
  2. DFS 回答连通性(连通块、判环);BFS 回答无权图最短路。
  3. 两者复杂度都是 O(n + m)(点数 + 边数)。

并查集 Disjoint Set Union

是什么:维护“谁和谁是一伙的”的结构:支持合并两个集合、查询是否同集合,接近 O(1)。

什么时候用:动态连通性、朋友圈、Kruskal 最小生成树。

怎么用
  1. find(x) 带路径压缩,unite(a, b) 按集合大小合并。
  2. 统计集合个数:对每个 i 先 find(i) 压平路径,再数 parent[i] == i 的个数。
  3. 初始化时 parent[i] = i

排序算法 Sorting

是什么:把数据按顺序排好。常用四种:插入、归并、快速、堆排序,都是 O(n log n) 或更好于 O(n²)。

什么时候用:需要自己实现(作业/面试)、或需要稳定排序时。

怎么用
  1. 日常直接用 std::sort(O(n log n));想保持相等元素原顺序用 std::stable_sort
  2. 要手写就记归并(稳定、需额外空间)和快排(平均最快、原地、不稳定)两种。
  3. 比较器必须是严格弱序,否则 sort 行为未定义。

双指针 Two pointers

是什么:用两个下标在序列上移动,把原本 O(n²) 的暴力枚举降到 O(n)。

什么时候用:有序数组求和、去重、原地删除、回文判断。

怎么用
  1. 相向双指针:一个从头、一个从尾,向中间靠拢(两数之和、回文)。
  2. 同向双指针(快慢指针):慢指针维护结果区间,快指针扫一遍(原地删除、去重)。
  3. 前提是要有单调性,否则指针移动没有依据。

滑动窗口 Sliding window

是什么:维护一个连续区间 [l, r],右端扩张、左端收缩,一路扫完。

什么时候用:连续子数组/子串的最值或计数问题。

怎么用
  1. 右指针 for 循环扩张,窗口不满足条件时 while 收缩左指针。
  2. 典型题:最长无重复子串、和 ≥ target 的最短子数组。
  3. 只有“单调性”成立时才能用:扩大会更容易满足、收缩会更难满足。

哈希表 Hash table

是什么:用哈希函数把键映射到桶,实现平均 O(1) 的插入和查找。C++ 里是 std::unordered_map / unordered_set

什么时候用:只想快速判断“在不在”、统计频率、配对查找,不要求顺序时。

怎么用
  1. std::unordered_map<int, int> cnt; ++cnt[x]; 统计频率。
  2. 查存在用 count()find()m[key] 会插入默认值。
  3. 需要按 key 有序遍历就换 map/set;哈希冲突严重时复杂度会退化。

前缀和 Prefix sum

是什么:预先算好前缀累加 pre[i+1] = pre[i] + a[i],之后任意区间和 O(1) 得到。

什么时候用:大量区间求和查询;配合哈希还能数“和为 k 的子数组”。

怎么用
  1. 区间和 a[l..r] = pre[r+1] - pre[l]
  2. pre[0] = 0,长度开 n+1,空区间也自然成立。
  3. 累加要用 long long:10⁵ 个 10⁹ 相加会溢出 int。

二分查找 Binary search

是什么:在单调序列里每次砍掉一半,O(log n) 找到边界;本质是“找最小/最大满足条件的值”。

什么时候用:有序数组查找、答案具有单调性的最优化问题(二分答案)。

怎么用
  1. 标准库:std::lower_bound(第一个 ≥ x)、upper_bound(第一个 > x)、binary_search(是否存在)。
  2. 手写模板:区间左闭右开,mid = left + (right - left) / 2 防溢出,满足条件就 right = mid。
  3. 二分答案:先写 ok(x) 判断函数,再二分最小的可行解。

深度优先搜索(DFS) Depth-first search

是什么:一条路走到黑,走不通就回退。递归实现,适合连通性、枚举所有路径。

什么时候用:网格连通块、树的遍历、排列组合、判环。

怎么用
  1. 四步模板:边界检查 → 进入即标记 → 遍历邻居 → 递归。
  2. 访问标记一定要在进入函数时立刻置位,否则会重复访问导致死循环。
  3. 递归深度大时可能爆栈,必要时改成显式栈或 BFS。

广度优先搜索(BFS) Breadth-first search

是什么:一层一层向外扩散,配队列实现;第一次到达某点的层数就是最短步数。

什么时候用:无权图最短路、最少步数、层次遍历。

怎么用
  1. 队列初始化装起点,dist 数组记录步数(-1 表示未访问)。
  2. 入队即标记:出队才标记会让同一个点重复入队。
  3. 需要输出路径时再开一个 parent 数组记录来路。

回溯 Backtracking

是什么:DFS 的一种:每步尝试所有选择,走不通就撤销选择换下一个。

什么时候用:全排列、组合、子集、八皇后、数独。

怎么用
  1. 模板三步:选(push + 标记)→ 递归 → 撤(pop + 取消标记)。
  2. “撤销”是灵魂:不撤销,下一次尝试会带着上一次的残留。
  3. 剪枝决定速度:排序后跳过重复元素、提前判断可行性。

贪心 Greedy

是什么:每步都选当前看起来最优的,并证明局部最优能推出全局最优。

什么时候用:区间调度、找零钱、部分最优化问题。

怎么用
  1. 经典例子:按结束时间排序后依次选不重叠区间。
  2. 用之前先想反例;证明不了就换 DP 或枚举。
  3. 贪心是否正确取决于问题结构(例如找零钱只有面值成倍数关系时才成立)。

动态规划(DP) Dynamic programming

是什么:把大问题拆成会重复出现的小问题,用数组把子问题答案存下来避免重复计算。

什么时候用:最优值问题且子问题重叠时:爬楼梯、最大子段和、背包、编辑距离。

怎么用
  1. 三步走:定义状态 → 写转移方程 → 定初值与答案。
  2. 最大子段和:cur = max(a[i], cur + a[i]); best = max(best, cur);
  3. 先想清楚“状态是什么、从哪些状态转移过来”,再动手写代码。

四、编程语言(C / Java / Python)

C 语言 C

是什么:面向过程、贴近硬件的通用语言:不隐藏内存细节,也不替你管理内存。

什么时候用:想搞懂指针、内存布局、编译链接这些底层概念时;也是学 C++ 与数据结构的前置。

怎么用
  1. 标准版本用 -std=c17;编译命令 gcc -std=c17 -Wall -Wextra -o app app.c
  2. 程序入口是 int main(void);没有类、没有异常、没有垃圾回收。
  3. 字符串是“以 '\0' 结尾的字符数组”,不是一种独立类型。

GCC 编译器 GNU Compiler Collection

是什么:把 C/C++ 源码编译成可执行文件的工具链;gcc 编 C,g++ 编 C++。

什么时候用:本地写 C/C++ 程序、写在线评测题目时每天都在用。

怎么用
  1. gcc -std=c17 -Wall -Wextra -o hello hello.c 编译并指定输出名。
  2. -c 只编译成目标文件(.o),-g 保留调试信息,-O2 开优化。
  3. -fsanitize=address,undefined 打开内存与未定义行为检测。
  4. 多个源文件一起编译:gcc -o app main.c util.c

动态内存(malloc / free) malloc / free

是什么:C 里在堆上申请和释放内存的一对函数:malloc 只要空间不清零,free 归还给系统。

什么时候用:数组大小要到运行时才知道、或对象的生命周期要超出函数时。

怎么用
  1. int *a = malloc(n * sizeof(int)); 申请后必须检查是否为 NULL
  2. 用完 free(a),并把指针置空,避免悬垂指针与重复释放。
  3. calloc 会清零,realloc 用来扩容。
  4. 现代 C++ 里这一步交给 std::vector / 智能指针(见 RAII)。

C 字符串 C string

是什么:\0 结尾的字符数组:长度靠遍历统计,容量与内容都要你自己维护。

什么时候用:用 C 处理文本时必须面对它;%sfgetsstrlen 都围绕它工作。

怎么用
  1. char buf[64]; 留出放 \0 的位置;用 %63s 限制读入长度。
  2. strlen 求长度(O(n))、strcpy 复制、strcmp 比较(不能写 ==)。
  3. 读整行用 fgets,注意它会保留行尾换行符。
  4. C++ 里直接用 std::string,不必再操心这些。

结构体 struct

是什么:把多个字段打包成一个自定义类型的语法;结构体数组、结构体指针是链表和树的起点。

什么时候用:表示“一个学生的姓名和分数”“一个区间的左右端点”这类成组数据时。

怎么用
  1. struct Point { double x, y; }; 定义;typedef 之后可以只写 Point
  2. 变量用 p.x,指针用 p->x(等价于 (*p).x)。
  3. 结构体按值传参会整体拷贝,大结构体要传指针并加 const。
  4. C++ 里 struct 与 class 只差默认访问权限。

预处理 #include / #define

是什么:编译之前对源码做的纯文本处理:展开 include、替换宏、处理条件编译。

什么时候用:所有 C/C++ 程序都在用;排查重复定义、宏展开问题时要知道它的存在。

怎么用
  1. #include <stdio.h> 引入系统头文件,#include "util.h" 引入自己的头文件。
  2. 头文件用 include guard(#ifndef / #define / #endif#pragma once)防重复包含。
  3. 宏是纯文本替换、没有类型与作用域,能用 constexpr / inline 函数就别用宏。

JVM 与字节码 Java Virtual Machine

是什么:Java 源码编译成字节码(.class),再由 JVM 加载执行;正是这一层让 Java 跨平台。

什么时候用:理解“为什么 Java 能一次编写到处运行”“为什么需要装 JDK”时。

怎么用
  1. javac Main.java 生成 Main.classjava Main 启动 JVM 运行。
  2. JVM 负责垃圾回收:对象不再被引用后自动回收,不需要(也不能)手动释放。
  3. 性能热点由 JIT 编译成机器码,所以长时间运行的程序会越来越快。

JDK Java Development Kit

是什么:写 Java 需要的开发包:包含编译器 javac、运行时 java、以及标准库。只装 JRE 只能运行、不能编译。

什么时候用:准备开发环境的第一步。

怎么用
  1. 安装 JDK 17 或 21(LTS 版本),验证 javac -versionjava -version 一致。
  2. 编译带中文的源码建议加编码参数:javac -encoding UTF-8 Main.java
  3. 文件名必须与 public 类名一致。

String 与 StringBuilder String / StringBuilder

是什么:Java 的 String 是不可变对象;频繁拼接要用可变的 StringBuilder。

什么时候用:处理文本、循环拼接字符串时。

怎么用
  1. 比较内容用 a.equals(b)a == b 比较的是引用。
  2. 循环里不要写 s += x(每次都新建对象),改用 sb.append(x)
  3. 常用方法:length()substringsplitjoinstrip()

集合框架 Collections Framework

是什么:Java 标准库的容器体系:List(有序)、Set(去重)、Map(键值)、Queue(队列),接口统一、实现可替换。

什么时候用:几乎所有需要存一组数据的地方;选错容器往往就是性能问题的根源。

怎么用
  1. ArrayList 随机访问快;HashMap 平均 O(1) 查找;TreeMap 有序 O(log n)。
  2. 统计频率的写法:map.merge(key, 1, Integer::sum)
  3. 遍历时不要直接 list.remove(...),用 removeIf 或迭代器。
  4. 自定义对象做 key 必须同时实现 equalshashCode

泛型 Generics

是什么:让容器与算法带上类型参数(List<String>),把类型错误从运行期提前到编译期。

什么时候用:使用集合、写通用工具方法时。

怎么用
  1. List<String> list = new ArrayList<>(); 声明时写类型,创建时可省略。
  2. 类型擦除:运行期看不到泛型参数,所以不能 new T[]、也不能对泛型做 instanceof
  3. 通配符:List<? extends Number> 只读、List<? super Integer> 可写。

受检异常 Checked exception

是什么:Java 把异常分成受检(必须处理或声明 throws)与非受检(RuntimeException)两类。

什么时候用:做 IO、网络、解析这些“可能失败”的操作时。

怎么用
  1. 受检异常必须 try-catch 或在方法签名上 throws
  2. 捕获要具体:先 catch (IOException e),最后才用宽泛类型兜底。
  3. 不要写空 catch 吞掉异常;至少打印日志或重新抛出。
  4. 资源用 try-with-resources 自动关闭。finally 用于必须执行的收尾。

继承与接口 extends / implements

是什么:Java 的方法默认动态绑定:父类引用指向子类对象时,调用的是子类实现(多态)。

什么时候用:需要“同一段代码处理不同具体类型”时。

怎么用
  1. 类单继承(extends),接口可以多实现(implements)。
  2. 重写方法建议加 @Override,让编译器检查签名。
  3. 接口只描述能力,抽象类可以带字段与部分实现。
  4. 只装数据的不可变类可以直接用 record

record record

是什么:Java 16 起的不可变数据类语法:一行声明,自动生成构造器、访问器、equals、hashCode、toString。

什么时候用:只想装一组数据、不需要继承时(DTO、坐标、区间、返回值)。

怎么用
  1. record Point(int x, int y) { };访问用 p.x()(方法,不是字段)。
  2. 可以给 record 加方法、实现接口。
  3. 字段不可变:想“修改”就创建一个新对象。

Stream API Stream

是什么:用链式写法对集合做过滤、映射、排序、统计:list.stream().filter(...).map(...).count()

什么时候用:处理数据集合、做统计与转换时;比手写循环更短也更易读。

怎么用
  1. 中间操作 filter / map / sorted 是惰性的,终止操作 count / sum / collect / forEach 才真正执行。
  2. 分组统计:collect(Collectors.groupingBy(f, Collectors.counting()))
  3. 流只能消费一次,重复使用会抛 IllegalStateException。

Python Python

是什么:动态类型、解释执行、语法极简的通用语言,标准库与第三方生态非常丰富。

什么时候用:写脚本、处理数据、做实验、搭原型时首选;也是数据科学方向的主力语言。

怎么用
  1. 运行脚本 python hello.py;快速试验直接敲 python 进 REPL。
  2. 缩进就是语法(惯用 4 个空格);语句末尾不写分号。
  3. 动态类型不等于弱类型:1 + "2" 会报错,不会隐式转换。

pip 与虚拟环境 pip / venv

是什么:pip 是 Python 的包管理器;venv 用来给每个项目建一套独立的依赖环境。

什么时候用:安装第三方库(如 pandas)、或不同项目需要不同版本依赖时。

怎么用
  1. python -m venv .venv 创建虚拟环境;激活后 pip install pandas
  2. Windows 激活:.venv\Scripts\activate;macOS / Linux:source .venv/bin/activate
  3. 把依赖写进 requirements.txtpip freeze > requirements.txt

列表 / 字典 / 集合 list / dict / set

是什么:Python 内置的四种容器:list(有序可变)、tuple(有序不可变)、dict(键值)、set(去重)。

什么时候用:几乎所有 Python 程序都在用;选对容器代码能短一半。

怎么用
  1. list 常用:appendextend、切片、sortedsum/max/min
  2. dict 计数:freq[w] = freq.get(w, 0) + 1collections.Counter
  3. set 去重:set(nums),判断存在 O(1)。
  4. 字典的键必须可哈希(列表不行)。

推导式 Comprehension

是什么:用一行生成列表 / 字典 / 集合:[x * x for x in range(5) if x % 2 == 0]

什么时候用:从已有数据构造新容器时,比 for + append 更短也更快。

怎么用
  1. 列表推导:[f(x) for x in seq if 条件]
  2. 字典推导:{name: i for i, name in enumerate(names)}
  3. 嵌套超过两层就该拆成普通循环,可读性优先。
  4. 生成器表达式 (x for x in seq) 是惰性的,适合流式处理大文件。

f-string f-string

是什么:Python 3.6 起的字符串格式化语法:f"{name} 得分 {score:.2f}"

什么时候用:拼接字符串与数值时,比 %format() 更直观。

怎么用
  1. 格式控制:{x:.2f} 两位小数、{x:>8} 右对齐、{x:,} 千分位。
  2. 可以直接写表达式:f"合计 {a + b}"
  3. 调试小技巧:f"{value=}" 会同时打印变量名和值。

Python 异常处理 try / except

是什么:用 try/except 捕获运行时错误;Python 强制你写明要捕获哪种异常类型。

什么时候用:处理外部输入、文件读写、类型转换等可能失败的操怍时。

怎么用
  1. try: ... except ValueError as e: ... 捕获具体异常。
  2. finally 一定会执行;with 用来保证资源释放(比 try/finally 更简洁)。
  3. 不要写裸的 except:,它会连键盘中断和真 bug 一起吞掉。
  4. 没有捕获的异常会打印完整调用栈,这是定位问题的第一手信息。

dataclass dataclass

是什么:用装饰器自动生成数据类的构造器、打印与相等判断:@dataclass class Student: name: str; score: int = 0

什么时候用:只装数据、需要清晰的 __init____repr__ 时。

怎么用
  1. 字段带默认值时,后面的字段也要给默认值(和函数参数规则一致)。
  2. frozen=True 可以得到不可变对象(可哈希、可做字典键)。
  3. 可以和方法混用;比手写 __init__ 少写一大堆样板。

pandas pandas

是什么:Python 的数据分析主力库:用 DataFrame(表格)做读取、筛选、分组、统计与导出。

什么时候用:处理 CSV / Excel 数据、做数据清洗与统计时;博客的数据科学线也围绕它展开。

怎么用
  1. 装:pip install pandas;读:df = pd.read_csv("a.csv")
  2. 统计:df["score"].mean();筛选:df[df["score"] >= 60];排序:df.sort_values("score")
  3. 分组:df.groupby("name")["score"].sum()
  4. 中文乱码多半是编码问题,试 encoding="utf-8""gbk"

模块与包 module / package

是什么:一个 .py 文件就是一个模块;用 import 引用;带 __init__.py 的目录是包。

什么时候用:把代码拆成多个文件、复用别人写的库时。

怎么用
  1. import json / from collections import Counter / import numpy as np 三种写法。
  2. if __name__ == "__main__": 让文件既能当脚本跑、又能被 import。
  3. 自己写的文件名不要叫 random.pyjson.py,会遮蔽标准库。