news 2026/10/21 17:57:33

论文复现包使用指南:解压体检、环境搭建与避坑实操

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
论文复现包使用指南:解压体检、环境搭建与避坑实操

简介:面向FPGA脉压工程开发的完整补充包,在作者此前发布的FPGA脉压项目基础上扩展完善,补全了遗漏的工程代码,也为此前下载者提供了可直接运行的完整方案。脉冲压缩是雷达与声呐信号处理中的常用技术,FPGA实现通常涉及分布式算法、并行滤波与IP核应用,这些环节均包含在内。包内以VHDL/Verilog源码为主体,同时提供do/Tcl/Bat自动化脚本、coe/mif系数与初始化文件、xci/dcp等IP核配置、xdc约束以及面向滤波/压缩模块的C测试激励,覆盖RTL设计、仿真验证到综合实现的主要环节。压缩包共739个文件,总大小176.42MB,适合有一定数字逻辑基础、希望学习脉冲压缩算法在FPGA上落地的工程师与研究生,已有2093人学习/下载。通过解压可直接复用完整工程框架,结合测试平台和运行脚本理解算法映射、时序约束与调试思路,也可基于中间文件快速展开二次开发与实验复现。

1. 拆开之前先看懂:lunwen_jiangwenbo2.zip 是个论文复现包

从某个资源站下载了一份叫 lunwen_jiangwenbo2.zip 的压缩包,文件名里既有“lunwen”又有“jiangwenbo2”,大概率是某篇论文的配套代码、数据和说明文档被打包成了一个 zip。这类包在从业者之间流传很广:拿到它,你就能在本地把论文里的方法跑起来,验证效果、对比自己的方案,甚至改造成自己的实验基座。但多数人一上来就双击解压、直接跑 train.py,结果被环境问题、路径问题、版本问题绊住,白折腾一晚上。这篇笔记想说的是:面对这样的压缩包,先体检,再搭环境,再复现,最后把它收编成自己的工具。适合刚入门的同学,也适合做实验对比时需要快速跑通一篇论文的老手。

2. 给压缩包做个体检:先看清包里有什么,再决定投入多少时间

解压这个动作本身没有技术含量,真正有讲究的是解压之前的心态和解压之后的第一步。我的习惯是:下载完 lunwen_jiangwenbo2.zip,先看一眼文件大小,再在终端里跑一条列出压缩包内容的命令,最后才决定要不要展开。很多人在这一步就踩了坑——解压出来一堆没头没尾的文件,连哪个是入口都不知道,只能凭感觉瞎试,越试越乱。

体检的目标是把“未知的 zip”变成“已知的项目”,接下来每一步才有的放矢。这一章我按自己实际处理论文包的顺序来:先讲这类包的标准构成,再讲怎么用命令盘清目录,最后给一套判断包是否完整的标准。这三步走完,你对这个包要不要花时间、值不值得复现,心里基本有数。

2.1 从 lunwen_jiangwenbo2 说起:论文复现包的标准三件套

一份论文复现包,无论来自哪个渠道,通常都由三部分组成:代码、数据、文档。代码部分包括模型定义、训练脚本、推理脚本、工具函数,是整个包的核心;数据部分要么是打包好的示例数据集,要么是 README 里的下载指引,负责让代码真正跑起来;文档部分则是 README、环境说明、实验结果记录这类文本,决定了你上手的速度。

我对这三件套的看重程度是:文档大于数据大于代码。原因是代码写的再乱,只要入口清晰,总能跑通;数据缺了,还能用小规模公开数据顶替验证通路;文档要是没有,连 Python 版本、依赖范围、数据集格式都要靠猜,时间成本直接翻倍。很多人拿到 lunwen_jiangwenbo2.zip 之后先翻代码,其实顺序反了,应该先找 README,把作者写的运行步骤读一遍再动手。

文件名里的 jiangwenbo2 通常是压缩包创建者留下的项目代号或命名习惯,不必过度解读,直接把它当成这个包的命名空间就好。真正决定你投入时间多少的,是下面三件套是否齐全,而不是文件名本身。

2.2 用 unzip 和 tree 在本地盘清目录结构

我一般会在专门的工作目录里解压,避免文件散落一地。先建目录,再解压到指定文件夹,然后用 find 只看两到三层的目录结构,最后用 ls -lh 看文件大小分布。一套命令下来,包的全貌基本就清楚了。

mkdir -p ~/paper_repro && cd ~/paper_repro unzip lunwen_jiangwenbo2.zip -d lunwen_jiangwenbo2 cd lunwen_jiangwenbo2 find . -maxdepth 2 -type d | sort ls -lh

这里-d参数指定了解压目标目录,比直接解压到当前目录干净得多;find . -maxdepth 2 -type d只列出两层以内的目录,让你先看到整体结构,而不是瞬间被几百个文件淹没;sort让目录按字母排列,方便浏览;ls -lh则能看出哪些文件是重量级的——比如超过 50MB 的文件,多半是预训练权重或数据集样本,这对后续判断很有帮助。

如果你用的系统里没有tree命令,用find完全够用。目录层级深的包,可以把maxdepth从 2 调到 3 再看一层。解压完成后,我通常还会再看一眼总占用空间,du -sh一行命令搞定,心里有个数。这里给你一个常见的论文复现包目录结构样例,实际解压出来的包大概率长得很接近:

lunwen_jiangwenbo2/ |-- README.md # 使用入口,最先读这个 |-- requirements.txt # 依赖清单,决定环境怎么搭 |-- configs/ # 训练/推理配置,yaml 或 py 格式 |-- src/ # 模型定义与工具代码 |-- scripts/ # 数据准备和入口脚本 `-- data/ # 样例数据,可能为空或带下载链接

这个结构不是某一份包的特权,而是论文代码包约定俗成的排布。你需要做的,是把自己解压出来的实际目录映射到这个结构上,找到 README、依赖清单、入口脚本这三个关键文件。

2.3 判断包是否完整的三个信号:README、依赖清单、入口脚本

体检的核心就一句话:这个包能不能独立跑通。我判断的标准是三个信号,缺一个都要提高警惕。

信号怎么检查缺失时的应对
README 或 readme.txt看包根目录是否存在该文件只能靠代码结构和注释硬猜,时间成本翻倍
依赖清单requirements.txt / environment.yml / pyproject.toml 任一环境要自己逐个试包,建议降低预期
入口脚本train.py / test.py / main.py / run.sh 任一先用 grep 找 argparse 定义,找到主入口

三个信号至少有两个存在,这个包才值得你花一晚上去复现。如果只有源码没有 README,我会先花 15 分钟快速扫一遍代码:看头部注释、看主函数命名、看有没有硬编码路径。能判断出结构就继续,判断不出就直接放弃,把时间留给下一个包。这不是胆小,是对自己时间的负责。

另外还有一个容易被忽略的判断维度:包的新鲜度。发布时间超过两到三年的包,依赖的老版本库很可能和新系统不兼容,复现成本会直线上升。如果你手头有同类型的、维护更活跃的包可选,我建议优先选择后者。体检做到这里,接下来就可以进入环境搭建了。

3. 环境搭建:三步骤让代码在本地跑起来

拿到一只体检合格的论文包,下一步是搭环境。这里我再强调一遍:百分之六十以上的“跑不通”,根因都出在环境上,而不是代码本身。你用的 Python 版本不合适、torch 版本和包内代码不匹配、缺少某个系统级编译工具,每一个都能让你卡在原地,而且报错信息看起来跟代码毫无关系,特别折磨人。

环境搭建这件事,有两条铁律:第一,永远用独立虚拟环境,别在系统 Python 里直接装;第二,永远先读依赖文件再动手,别凭感觉挑版本。按这两条铁律走,大部分环境问题都能在最开始就被拦住。

3.1 先读依赖文件,再选 Python 环境

解压完成后,不要上来就敲 pip install。先打开 requirements.txt 看依赖,再看 README 里有没有环境说明。你需要从里面提取三个信息:Python 版本要求、深度学习框架版本要求、有没有特殊系统依赖。这三个信息决定了你虚拟环境怎么建。

我常用的方案是用 conda 建独立环境,因为老论文包经常要求 python=3.6 或 3.7,系统自带 Python 根本没法切换版本,conda 可以一条命令搞定。下面是一个典型流程,其中 pytorch 版本按包内 requirements 声明为准,这里只是示范:

conda create -n jwb_repro python=3.8 -y conda activate jwb_repro pip install -r requirements.txt

jwb_repro是我给这个环境起的名字,取自 jiangwenbo2 的缩写;python=3.8是举例,实际版本要跟 requirements.txt 里的声明对齐,比如老包可能要求 3.7。第三步用pip而不是conda安装依赖,是为了完全对齐 requirements.txt 里锁定的包版本,conda 有时候会自作主张帮你“升级”某些包,反而破坏了版本关系。

如果你机器上没有 conda,用 Python 自带的 venv 也可以,效果类似:

python3 -m venv .venv_jwb source .venv_jwb/bin/activate pip install -r requirements.txt

注意 Windows 下激活命令是.venv_jwb\Scripts\activate,路径略有不同。这两套方案任选一套,关键是环境要独立、版本要锁定,后面排查问题时才不会被无关的包干扰。

3.2 装依赖时的高频坑:镜像源、版本冲突、编译工具

依赖安装这一步,几乎人人都会遇到问题。最常见的三个:下载速度慢、版本冲突、缺编译工具。我分别说一下自己的处理方式。

下载慢的问题,解决办法是临时指定 pip 镜像源。注意是“临时指定”,不要改全局配置,避免影响到其他项目的安装行为:

pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

-i参数在本次命令里把 PyPI 源切换到了清华镜像,下载速度快很多。如果某些包还是装不上,可以再加--timeout 60 --retries 3,给网络请求留出更多余量。

版本冲突的问题,常见表现是 requirements.txt 里只写了包名没锁版本,或者锁的版本跟 Python 版本对不上。我的原则是:先装主框架,再装周边工具。以深度学习包为例,先把 torch 对应版本装好,再装 torchvision 和其他库,因为周边库的兼容性往往是围绕主框架版本展开的:

pip install torch==1.8.0 torchvision==0.9.0 pip install -r requirements.txt

这里先用主框架版本兜底,再用 requirements 装剩下的。如果依赖文件里已经写了 torch,这一步可以跳过,直接跑 requirements 即可。遇到包之间的严格版本约束,不要硬解,先看报错提示的是哪个依赖链,优先满足星星数量最多的那个包。

缺编译工具的问题,主要出现在 Windows 上,安装某些带 C 扩展的包时,报错信息里会出现Failed to build xxx或Microsoft Visual C++ 14.0 is required。这是因为部分包没有预编译好的 wheel,需要现场编译。解决办法是安装对应的构建工具链,或者干脆换一个带预编译 wheel 的 Python 版本。在我的经验里,这类包直接换 conda 安装往往更快,因为 conda 的包大多有编译好的版本。

3.3 环境自检:用两条命令确认光线打通

依赖装完不代表环境没问题,import 能过才算数。我每次都会在项目根目录跑两条自检命令,一条验证底层框架,一条验证项目内模块。两步都过,才敢说环境搭好了。

python -c "import torch; print(torch.__version__, torch.cuda.is_available())" python -c "from src.model import create_model; m = create_model(); print(m)"

第一条命令输出 torch 版本和 CUDA 是否可用,确认深度学习框架和 GPU 驱动正常。第二条命令导入项目内部的模型模块,确认代码本身没有被环境问题卡住。注意第二条里的src.model和create_model只是示例路径,实际要以你解压出来的包内结构为准——这也是为什么我说先读包结构再动手。

如果第二条报ModuleNotFoundError或No module named src,多半是项目根目录没有被加入 Python 的模块搜索路径。解决办法是在项目根目录下用PYTHONPATH=.前缀运行:

PYTHONPATH=. python -c "from src.model import create_model; print(create_model())"

PYTHONPATH=.把当前目录加入搜索路径,让src包可以被找到。这份环境算是通了,但别高兴太早,接下来数据准备和运行配置还有不少坑等着。

4. 复现主流程:数据、训练/推理、指标对齐

环境端到端跑通,只意味着“代码能加载”,离真正复现论文结果还差三步:数据准备、启动训练或推理、结果对齐。这三步每步都有独立的坑,尤其是数据这一步,坑最深。很多人在环境上花了两个小时,却在数据路径上栽了跟头,一晚上就耗没了。

复现的思路应该是:先用最小配置跑通整个流程,再逐步恢复论文的原始设置。不要一上来就按论文里的大 batch、大分辨率跑,那样一旦出错,排错成本非常高。先把链路打通,再逼近论文条件,是效率最高的路径。

4.1 数据准备:数据集放哪、路径怎么改

论文包通常不把完整数据集打在 zip 里,最多放几张样例图,剩下靠 README 里的下载地址。解压之后的第一件事,是找到配置文件中控制数据路径的字段,把自己的数据集放到对应位置。常见做法是把数据放进包根目录下的 data 文件夹,或者用软链接指向你本机已有的数据集:

mkdir -p data ln -s /path/to/your/dataset data/dataset_name

用软链接而不是直接复制,好处是省磁盘空间,尤其当数据集有几十 GB 时,复制一份纯属浪费。-s参数让链接指向原路径而不是复制文件,/path/to/your/dataset换成你本机的真实路径。注意包内有些相对路径写的是./data/dataset_name,只要你的软链接名字和配置里的目录名一致,就能认出来。

数据路径确认后,再检查配置文件里的数据划分和加载参数。一个典型的 yaml 配置长这样:

data_root: ./data/dataset_name train_split: train eval_split: val batch_size: 8 num_workers: 4

data_root是数据集根目录,train_split和eval_split是训练、验证子集的目录名,这两个名字经常和你的数据集结构不一致,需要按实际调整。batch_size和num_workers是本阶段最重要的两个参数——前者决定显存占用,后者决定 CPU 预处理速度,后面排查问题时会频繁跟它们打交道。

4.2 启动训练或推理的最小命令

数据准备好之后,先别急着按论文默认参数跑。找 README 里推荐的启动命令,如果作者写了python train.py --config ...,那就用这个入口。大多数论文包的入口脚本长得很像,但名字各不相同,train.py、run.py、main.py、demo.py 都有可能出现。不确定的时候,用 grep 搜一下脚本里的参数解析器,就能定位主入口:

grep -rl "argparse.ArgumentParser" --include="*.py" .

这条命令会在当前目录的所有 Python 文件里搜索argparse.ArgumentParser,列出所有定义了命令行参数的脚本,从里面挑一个名字最像主入口的。-rl表示只列出文件名不显示匹配行,--include="*.py"限定只搜 Python 文件。找到入口后,最小训练命令长这样:

python train.py --config configs/experiment.yaml

如果确认环境没问题但资源有限,可以先加一个收敛到最小规模的参数组合,用 1 个 epoch 和更小的 batch 跑通全流程:

python train.py --config configs/experiment.yaml --epochs 1 --batch_size 2

--epochs 1的意思是只跑一个训练轮次,纯粹为了验证代码通路,不追求任何指标;--batch_size 2把单次送入的样本数降下来,显存不够时的降级策略。真正复现时,这两个参数要改回论文里报告的值。需要做推理验证时,命令也类似:

python test.py --checkpoint checkpoints/best_model.pth --input samples/sample_001.png

--checkpoint指定权重文件路径,--input指定待推理的输入文件。这段命令的意图很直接:用训练好的权重跑一张样例图,确认推理链路也正常。在这里,checkpoints/best_model.pth是包的常见命名,实际要看包内有没有这个文件,没有的话先用 5.1 节里的方式处理权重缺失问题。

4.3 结果对齐:怎样算复现成功

跑通流程和复现结果是两码事。判断复现是否成功,我习惯分两步:先看趋势,再看数值。趋势指训练过程中损失函数是否在下降、验证指标是否在上升,只要曲线方向合理,说明代码逻辑没大问题;数值指最终指标和论文报告的差距,这才是复现成功的最终标尺。

在数据集、随机种子都一致的前提下,差距在 1-2 个百分点内通常算稳定复现;差到 5 个点以上,就要回头查数据预处理、类别数、损失函数权重这些细节。预处理顺序是复现翻车的第一高发区,比如 Resize 和 RandomCrop 的顺序不同、归一化的均值方差写错,指标就会差出一个身位。检查预处理的一条快捷命令是把训练用的变换函数直接打印出来:

python -c "from src.dataset import get_transform; print(get_transform())"

对比论文里描述的数据增强流程,逐行核对有没有缺项或顺序颠倒。这一步排查掉之后,如果指标还不对,再看训练轮数和学习率调度,最后才怀疑模型结构本身。按这个顺序排错,大多数“复现失败”都能找到原因。

5. 论文复现包避坑实录:四个高发问题与排查路径

论文包跑不通的背后,原因高度集中。下面这四条,是我在折腾这类包时反复遇到的类型,每一条都值得你提前看一眼,真遇上了,能省下几个小时排查时间。这里我按“现象、原因、解决”来写,方便你对照排查。

5.1 解压后找不到预训练权重,模型加载直接报错

现象:运行 train.py 或 test.py 时,日志报出FileNotFoundError或unexpected key in state_dict,一看就是权重文件缺失或格式不对。

原因:分享漏传了权重文件,或者是用 Git LFS 存储的权重只在 zip 里留下一个文本指针,真正的二进制数据还在远程。zip 本身不完整,代码却按完整包来写,自然加载失败。

解决:先检查 README 里有没有权重下载地址或自动下载脚本;如果没有,把目标降级为“先用随机权重跑通流程”,确认训练、评测、保存的链路都正常后,再回头补权重做最终验证。千万别卡在这一步不动,你不是来审稿的,先把通路打通要紧。

5.2 requirements 版本冲突,装一个包顶掉另一个包

现象:pip install 时一切顺利,但运行时报 import 错误,比如 torchvision 和 torch 版本不配套,某个 API 在已装版本里不存在。

原因:requirements.txt 只写了包名没锁版本,或锁的版本与当前 Python 版本不兼容。pip 按依赖解析顺序安装时,后装的包可能把先装的包升级到了不兼容的版本。

解决:不要在已经装乱的环境里反复试版本,那是给自己找罪受。删掉环境重新建,先装主框架再装周边工具,顺序固定为:主框架、视觉/文本工具库、其他辅助库。装完能跑之后,立刻用pip freeze > requirements_lock.txt把当前可跑版本锁定下来,下次直接按锁文件装。

5.3 训练指标和论文对不上,结果忽高忽低

现象:同一份代码、同一条命令,跑了两次指标差好几个点;或者曲线形状对、绝对值低一截,怎么调都上不去。

原因:随机种子没固定、数据增强顺序和论文不一致、BatchNorm 的统计量在训练和测试模式下没切换。这三个原因单独拎出来都很难发现,凑在一起就是复现路上的玄学困扰。

解决:先在训练脚本最开头固定随机种子,把这段代码放到 import 之后、任何数据处理之前:

import random import numpy as np import torch def set_seed(seed): random.seed(seed) np.random.seed(seed) torch.manual_seed(seed) torch.cuda.manual_seed_all(seed)

在 main 入口调用set_seed(42)即可,这样每次跑的结果理论上应该完全一致。固定种子后仍对不上,再对照论文检查数据增强顺序,重点看归一化、缩放、裁剪的顺序,这三者的先后顺序直接影响最终指标。最后确认测试时模型处于model.eval()模式,不要带着训练阶段的 BatchNorm 统计量去推理。

5.4 同一份代码换机器就报显存不足或 CPU 龟速

现象:作者机器上能跑通的一份代码,换到你的机器上直接报CUDA out of memory,或者没有 GPU 的机器上用 CPU 跑,一个 epoch 要跑一小时。

原因:batch_size 和 num_workers 是作者按照他自己的显卡显存和 CPU 核数调整过的,换机器后资源条件不同,原参数自然跑不动。

解决:先减 batch_size,这是最直接的手段。如果减到 2 还不够,就用梯度累积策略,用时间换显存:

batch_size: 2 gradient_accumulation_steps: 4

gradient_accumulation_steps: 4的含义是攒够 4 个小 batch 的梯度再更新一次模型参数,效果上等价于batch_size: 8,但显存占用只有原来的四分之一。代价是训练时间变长,但至少能跑起来。CPU 机器上跑不动是常态,要么把数据集切成小子集验证通路,要么把num_workers调大加速数据读取,接受“只能验证、不能真正复现”的现实,别跟自己机器过不去。

6. 从复现到自用:把压缩包改造成稳定实验框架的一个技巧

论文包跑通只是开始,真正让代码发挥价值,是把它收编进你自己的实验流程。我的习惯是每拿到一个新包,就在包旁边建三个目录:runs、notes、patches。runs 放每次实验的输出,notes 放复现笔记,patches 放对源码的改动。三个目录分工明确,三个月后回头看,你依然能快速定位当时的实验状态。

跑实验时,用带时间戳的输出目录,保证每次实验的结果不互相覆盖:

mkdir -p runs/exp_$(date +%Y%m%d_%H%M%S) python train.py --config configs/experiment.yaml \ --output_dir runs/exp_$(date +%Y%m%d_%H%M%S)

$(date +%Y%m%d_%H%M%S)会生成类似20250601_143000的时间戳字符串,保证每次实验的输出目录唯一。--output_dir这个参数名不是所有包都有,具体看 README 里写的参数名,没有的话就手动改配置文件里的输出路径。这个习惯排除了“结果被覆盖”这一后悔事故。

我之所以强调改造习惯,是因为论文复现包的本质是“能跑但没考虑长期维护”,你今天改一行预处理,明天可能就忘了。把改动集中在 patches 目录里,以统一 diff 的形式保存,源码保持接近原版,就能随时回到可复现的状态。

我第一次折腾这类论文包时就是吃了没记录的大亏。当时跑通后手痒改了两行数据增强的代码,隔几天想回归到第一版结果做对比,却怎么都找不回当初的配置,硬生生多花了一个周末重新调参。从那以后,我每次跑实验前先在 notes 里写一句话:这次要验证什么、改了什么、期望看到什么。跑完再把实际结果和一句话结论补上。三个月后回看,这些笔记比代码注释管用得多。这个习惯没什么门槛,却能让一次性的复现变成可持续迭代的实验资产。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/21 17:57:03

Apollo-11导航计算机软件复现:高可靠嵌入式容错与实时调度实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/21 16:42:34

应用文写作教学大纲文档的工程化设计与自动化生成

简介:《应用文写作教学大纲》面向四年制本科各专业学生,是一份通识基础课的教学指导文件,旨在系统培养校园生活与未来职场中所需的实用写作能力。资源包共1个docx文件,大小约18KB,内容涵盖课程性质、教学目标、教学内容…

作者头像 李华
网站建设 2026/10/21 12:00:59

IDEA 2025.3升级全解读:新界面、索引优化与迁移避坑指南

很多朋友发消息问我:“IDEA 2025.3 更新后到底多了哪些东西?怎么网上都在说骚操作跟不上?”这里先统一回复一下:不是跟不上,是这版确实把很多入口藏得比较深,还顺手改掉了一批老默认行为。作为从2018年就开…

作者头像 李华
网站建设 2026/10/20 1:34:04

坚持冥想1772天:普通人五年的正念练习经验与避坑要点

一开始看到"A同学说他冥想一千七百七十二天"我先是愣了下,随即会心一笑,还有三天就满五年了。一千七百七十二天,差不多就是快五年不间断的每日练习,这个数字放在任何长期习惯里都算得上一个里程碑,放在冥想这…

作者头像 李华
网站建设 2026/10/21 6:09:08

牛客刷题第5篇:从刷题到解题,建立复盘与记录的方法论

这里在牛客上刷题第 5 篇记录。第 5 篇这个位置挺有意思,一方面是基础语法、经典数据结构已经过了几轮,很容易进入"一看题就会、一提交就卡壳"的状态;另一方面也差不多到了该总结方法论的时候。刷题进度过半之后,真正有用的不是又做…

作者头像 李华
网站建设 2026/10/21 10:14:47

交换数组最小值和最大值:核心是下标定位与边界条件处理

1. 先把这个题目的真实考点说清楚“交换最小值和最大值”这句题目,我见过太多人把它当成一道送分题来做。但实际写代码的时候,能一次写对并扛住所有边界测试的人,真没那么多。先从最朴素的直觉说起。给你一个数组[2, 5, 1, 9, 3],…

作者头像 李华