ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

LeetCode Editor插件:在IDEA里完成刷题全流程

LeetCode Editor插件:在IDEA里完成刷题全流程

写 IDEA 插件评测系列写到第 112 篇,今天聊聊 LeetCode Editor。说实话,这个插件是我自己刷算法题的主力工具,也是后台留言里被点名次数最多的一类。它的定位很简单:把 LeetCode 的题库、题目描述、代码提交和测试反馈全部嵌进 IntelliJ IDEA。以前我刷题是浏览器和 IDE 来回切,看题切回来,写几句再切过去看用例,写完复制到网页跑测试,失败再复制回来改,整个过程琐碎而且特别打断思路。装上它之后,刷题的完整闭环——看题、写码、跑用例、提交、看反馈——都在编辑器里完成。这篇我会从安装、登录、配置、核心功能一路讲到常见坑位,适合准备面试高频刷题的开发者,也适合想把手头刷题流程整理得更干净的人参考。

1. 为什么刷算法题要放在 IDE 里做

1.1 浏览器刷题到底缺了什么

很多人习惯在网页上直接写题,觉得 LeetCode 自带编辑器够用了。确实,简单题写个二十行代码没问题,但一旦题目开始涉及复杂的状态设计、边界条件或者像树、图这种需要肉眼“建模”的类型,网页编辑器的劣势就非常明显:没有代码补全,没有智能提示,没有润色后的格式化,错误信息就是一行小字,想重构一下代码还得小心翼翼地手动改。更麻烦的是,你在网页上的代码是不会进你本地代码库的,刷了一百道题,回头想复习,发现网站上看过的草稿要么没保存,要么就是乱七八糟的一堆散代码。

还有一个很多人没意识到的问题:面试刷题本质上是在训练编码习惯。你在 IDE 里写,会自动养成用快捷键、用重构、用格式化、用快速修复的习惯,这些习惯最后会带到面试现场的在线编辑器里。反过来,如果平时只在网页编辑器里裸写,大脑对编码工具的依赖会越来越弱,看似无所谓,实际上是在持续放弃 IDE 提供的所有辅助能力。

浏览器刷题还有一个隐藏成本:上下文切换。人脑从“阅读题目”切换到“动手编码”本身就需要几秒钟的注意力重建,如果这个切换每小时发生十几次,一天下来损耗非常大。我自己的体验是,把做题环境固定在一个窗口后,思维连贯性明显好很多,浪费在“复制粘贴、来回切换”上的时间基本降为零。

1.2 LeetCode Editor 到底搬进来了什么

LeetCode Editor 做的事情,可以概括成一句话:把 LeetCode 网站上的“做题台”搬到 IDEA 里。它有一个专门的面板列出题库,按难度、标签、状态分类;双击一道题,会在本地目录生成一个带题目标题和描述的文件;右边是题目内容,左边是代码区。写完代码,可以直接用自定义输入跑测试,跑完没问题再点提交,提交结果会返回执行时间、内存占用和击败比例。

注意一点,这个插件并不是把 LeetCode 整个网站镜像下来,它本质上是通过接口和 LeetCode 服务端通信。你在 IDEA 里跑测试或者提交,实际执行代码的是 LeetCode 的服务器,不是你的本地环境。这个机制的优点是和网页做题环境完全一致,比如那些坑人的边界输入、返回值格式、类名要求,都不会出现“本地能跑但提交就错”的偏差。缺点是没有离线能力,而且如果账号状态失效或者网络抖动,测试和提交就会报错。

1.3 适合谁,不适合谁

如果你是准备校招、社招面试的开发者,每天有固定的刷题量,这个插件非常值得用。它适合那些希望代码产物落到本地、可以被 Git 管理、可以被 IDE 全部能力加持的人。对我来说它最大的价值不是省那几秒钟,而是让刷题这件事变成一个真正的工程活动——每一道题都是一段可以回看的代码,有提交记录,有解法思路的注释,过段时间还能翻出来复习。

但也有不适合的场景。如果你只想零碎地每天打开网页刷一两道简单题,不想在本地留下任何文件,那装这个插件反而是负担。另外要提前说清楚:它虽然在 IDEA 里写代码,但 Run Test 和 Submit 都是调用远程接口,所以像本地断点调试这种功能,默认情况下是没法直接做的。你可以在生成的文件里临时加一个 main 方法自己构造输入,一样能调试,但那是额外操作,不是插件开箱即用提供的。

2. 安装、登录和配置,先把环境理顺

2.1 从插件市场安装并重启

装插件没什么特别,打开 IDEA,进入 Settings 或 Preferences 里的 Plugins,切到 Marketplace 页签,搜索框输入 LeetCode Editor,认准那个名字完全一致的插件,点击 Install,然后重启 IDE。重启之后,右侧工具窗口栏会出现一个 LeetCode Explorer 面板,插件就算装好了。

我遇到过一些朋友说装完没有面板,排查下来大多是两个原因:一是装完没有重启,IDEA 对插件安装后的工具窗口注册很多时候必须重启才生效;二是 IDEA 版本太老。这个插件在 2018.1 以上的版本基本都能用,但个别 2020 到 2022 之间的版本会有短暂的不兼容期,如果插件市场提示当前版本不兼容,可以到开源社区下载对应版本的插件包,走 Install Plugin from Disk 安装。我建议优先在插件市场装,因为市场渠道的版本通常已经经过兼容性验证,升级也会自动跟上。

2.2 四个关键配置项逐个说清楚

安装完成后,先别急着抓题,去 Settings 的 Tools 下面找到 LeetCode Plugin 配置页,把环境理顺。这里有几个配置项会直接影响你之后的使用体验,我按重要性一个个说。

配置项建议值为什么重要
URL根据你注册的站点选账号和站点必须匹配,这是登录失败最常见的根源
Login Type推荐 Cookie 登录密码登录经常碰到验证码,Cookie 方式更稳定
Code Type你最常用的语言决定生成文件的代码块和语言类型,后面可以改
Temp Dir一个专门的刷题目录所有题目文件都存在这里,建议单独建目录别跟项目代码混一起
File Name默认或带题号的格式决定生成文件名,影响排序和查找
Timeout默认即可,网络差就调大跑测试和提交是远程请求,超时太短容易误报失败

这里重点聊一下 URL 和 File Name。URL 下拉框里有两个选项,一个是国际站,一个是国内站。很多人注册的是国内站账号,结果配置页选的是国际站地址,登录永远 401 或者弹验证码,折腾半天才发现账号和站点不匹配。这个坑太常见了,我后面会在常见问题里专门展开。File Name 配置项很多人忽略,默认生成的文件名就是题目标题的英文驼峰,比如 TwoSum 这种。但你想按题号排序复习,最好在变量配置里加上题号前缀,格式改成类似“题号+标题”的组合,这样本地目录里所有文件都能按编号排好,回头看整个刷题历程一目了然。

Temp Dir 也很关键,比你想的重要。默认路径往往放在用户目录下,刷了上百道题之后文件散落在系统盘,想同步到自己的代码仓库非常别扭。我建议在本地单独建一个目录,或者干脆在某个项目里划一个子目录专门放题,比如 leetcode/editor/cn 这样。配置好之后,所有题目文件都稳定落在固定位置,后续接 Git 管理就非常简单。

2.3 登录方式:Cookie 登录比密码登录省心

登录这块是插件使用中出问题最多的一环,我多说几句。配置页里 Login Type 有 Password 和 Cookie 两种,开发者也明确说过密码登录在某些站点上很容易被验证码拦截,因为网站端对非浏览器环境的登录请求本身就有风控。如果你用密码登录一直失败,别硬试,直接切到 Cookie 方式。

Cookie 登录的操作不复杂:先用浏览器登录 LeetCode,成功进入做题页之后,按 F12 打开开发者工具,在 Network 或 Application 面板里找到当前页面的 Cookie 值,复制整段字符串,粘贴到插件配置的 Cookie 输入框,保存后点登录。这里有个安全提醒:Cookie 相当于你的登录凭证,粘贴到 IDE 之后最好不要截图发给别人,也别把配置目录里的文件随便同步到不信任的地方。

还有个细节:用 Cookie 登录之后,如果过了一段时间测试提交开始报鉴权异常,通常就是 Cookie 过期了,重新去浏览器复制一遍再粘进来就行。这个动作不频繁,但你要知道它存在,别以为是插件坏了。

3. LeetCode Explorer 与核心功能拆解

3.1 做题入口:右侧工具窗口

插件装好并登录成功后,点右侧的 LeetCode Explorer 标签,能看到一个完整的题库工具窗口。面板里默认分类包括全部题目、难度分组、标签分组,还有你自己的收藏列表。每条题目后面会显示难度,有些版本还支持用不同图标标记已通过、尝试过、未做过的状态。

我一般会先切到难度分组,把 Easy 当成热身,Medium 是主力,Hard 看心情。标签分组也很好用,刷专题的时候特别顺:想集中练动态规划,直接点 Dynamic Programming 标签,出来的全是相关题,不用自己在网页上一个一个翻。搜索框可以按题号或者标题关键词定位题目,这个不用多解释,刷到一定量之后搜索是最高频操作。

这个面板和 IDEA 原生工具窗口一样,可以拖拽、停靠、调整宽度,我习惯把它放在右侧并拉得窄一点,给代码区留更多空间。配合 IDEA 的分屏能力,还可以左边打开自己的笔记文件,右边做题目,复习效率会高很多。

3.2 打开一道题之后发生了什么

双击题目,插件会在你配置的 Temp Dir 下生成一个代码文件,同时右边的 Description 面板会渲染出这道题的完整描述。生成的文件名按你配置的 File Name 格式来,文件内容大体上由三部分组成:题目信息的注释头、package 声明和 import,以及一个以题目英文名命名的类骨架,类里面已经写好了 LeetCode 给你定义的方法签名,你只需要填充方法体。

这里有一个非常重要的细节:生成代码里有一段类似leetcode submit region begin(Prohibit modification and deletion)和leetcode submit region end(Prohibit modification and deletion)的注释标记。这段标记是用来圈定“提交代码范围”的,插件向 LeetCode 提交时,只会抽取这段标记范围内的代码发过去,范围外的辅助方法、测试代码、import 语句都不会被提交。

所以请你记住:别手一抖把这两行标记删了,删了以后提交行为会变得非常诡异,轻则多余的代码被一起提交导致编译错误,重则提交内容为空。如果你在类的外面写了私有辅助方法,并且希望它被提交到 LeetCode 一起编译,那就要把辅助方法也放到这段标记范围里面。这是插件原理层面的一个核心知识,理解了它,你就能自由地在文件里写测试代码而不影响提交。

3.3 Run Test 和 Submit 的真实工作机制

这两颗按钮才是刷题闭环的关键。Run Test 点击之后会弹出一个输入框,让你粘贴自定义测试用例,输入格式就是 LeetCode 的原始输入格式,多个参数之间用换行分隔。举个例子,如果一道题接收一个整数数组和一个目标值,输入就像下面这样:

[2,7,11,15] 9

然后插件会把你的代码、题目编号、这些输入一起打包发送给 LeetCode 服务端,请求它在服务器环境里编译运行,再把结果返回回来。所以肉眼上你是在 IDEA 里点按钮,实际上代码是在远端跑的。结果展示区会清楚显示执行是否通过、预期输出是什么、实际输出是什么。

Submit 的逻辑类似,只是它走的是提交接口,跑的是全部测试用例。返回结果里会告诉你是 Accepted 还是 Wrong Answer,如果是 Wrong Answer,还会给出第一个失败的用例和预期输出对比。如果是 Accepted,通常会显示运行时间、内存占用以及击败了百分之多少的提交,这个数据跟在网页上看到的完全一致,因为就是同一个接口。

理解了这个机制,你就能解释很多使用上的“怪事”,比如为什么网络波动时跑测试会转很久,为什么提交偶尔超时,为什么有时候插件没报错但 LeetCode 里看不到提交记录。本质上都只是因为它在做远程调用,不是本地执行,别把它当成一个简单的本地单测工具就行。

4. 实操全流程:从选一道题到提交通过

4.1 选题:按难度、标签和状态筛选

我以一个具体场景串一遍完整流程,你们感受一下真实使用节奏。晚上准备刷题,打开 IDEA,点开 LeetCode Explorer,先切到“全部题目”按通过率排序,或者直接在搜索框输入题号。找到目标题之后,我会习惯性看一眼右侧 Description 里的描述,确认没有理解偏差,然后再双击打开代码文件。

如果你在刷一个专题,比如“二叉树遍历”,那就切到 Tree 标签,选一道中等题。选题这个动作在插件里被压得非常小,几乎不用思考,这也是它对我来说价值最大的地方——刷题最大的阻力就是“打开正确题目的成本”,插件把成本降到了双击一下。

4.2 编码:用上 IDEA 原生能力

题目文件打开之后,你就拥有整个 IDEA 的编辑能力了。代码补全、自动导入、格式化、重命名重构,全部可用。长期在浏览器编辑器里写题的人第一次用这个插件会有一种“手放开的感觉”,尤其是写复杂递归或者边界条件多的题目时,补全和 IDE 的编译检查能省很多低级错误。

我写题的时候一般会先看一眼生成的方法签名,确认参数类型和返回类型,然后在方法体里实现。如果有需要临时验证的逻辑,我会在submit region之外写几个辅助方法,或者直接在 main 方法里构造测试数据。注意刚才说的,提交范围外的代码不会被打包,所以随便写,不用担心污染提交。

4.3 自定义用例测试

写完后点 Run Test,弹窗里按输入格式填用例。拿两数之和那种题举例,数组一行,目标值一行,点开始测试,几秒后返回结果。如果通过,面板会显示输出符合预期;如果不过,会把你实际的输出和期望输出并排摆出来。

这里我有个经验:空数组、只有一个元素、全是负数、超长输入这些边界用例,一定要在你自己的测试里先跑一遍,返回结果会非常直观地告诉你哪里崩了。跑测试的成本比网页上复制粘贴低太多,所以更愿意把用例想细,这其实是在训练写测试意识,对面试也是有帮助的。

4.4 提交与结果分析

测试没问题,点 Submit。返回 Accepted 的话,会看到运行时间、内存占用和击败比例。这几个数据我会看一眼,但说实话不用太焦虑,击败比例受提交样本影响波动很大,同一份代码不同时间提交可能差出二十个百分点。更值得关注的是有没有超过时间限制(Time Limit Exceeded),如果超时,说明复杂度确实有问题,得回 IDE 优化逻辑。

如果偷懒没有充分测试就提交,也能通过返回的失败用例反推问题,但那个用例通常是最刁钻的那种,改起来更费劲。所以我现在的习惯永远是:先在本地把自定义用例跑顺手了再提交,很少拿提交按钮当测试按钮用。

4.5 复盘:代码去了哪里

提交通过后,代码文件已经存到你的 Temp Dir 里了。我不会立刻走,而是会在文件头部注释区补两句这道题的思路要点,比如“用哈希表记录已出现的值和下标,时间 O(n)”。这个动作看起来不起眼,但每到复习阶段,作用非常大。这个目录本身受 Git 管理,所以每道题都有历史提交记录,过一个月回头看一个月前的自己写了什么代码,思路和现在的差别一眼就能看出来。

5. 高频问题速查与避坑记录

用这个插件快两年,踩过不少坑,也帮朋友排查过不少问题,我整理一张速查表,按优先级排好,遇到问题先对照着看。

现象最可能的原因处理思路
登录一直失败URL 站点和注册账号不匹配确认账号属于哪个站点,切换 URL 重新登录
密码登录弹验证码非浏览器环境触发风控改用 Cookie 登录
题库面板空白插件未完成登录或网络受限重新登录,检查 Cookie 是否过期
跑测试一直转圈网络波动或超时设置太短调大 Timeout,检查网络环境
提交报鉴权错误Cookie 过期重新去浏览器复制 Cookie 粘贴进来
生成文件乱码项目编码非 UTF-8把 Editor 的编码统一设置为 UTF-8
提交内容异常动了 submit region 标记检查标记是否完整,别删注释行
插件面板不见未重启 IDEA 或版本不兼容重启 IDE,必要时从本地安装兼容版本

5.1 账号登录的坑

账号问题占这个插件出问题的四成以上。最多的情况就是注册了国内站账号却选国际站 URL,或者反过来,登录时报 401,插件提示用户名或密码错误,其实根本不是密码错,而是站点选错了。判断方法很简单:你在浏览器里打开你选的站点,看看能不能用这个账号密码登录,如果能,那就是插件配置问题;如果不能,说明账号本来就属于另一个站点。

另外一个坑是很多人忽略的:登录信息不是你登录一次就永远有效,Cookie 会过期,风控策略也会变。如果某天突然所有测试都失败,先重新登录一次再排查别的,别一上来就怀疑插件坏了。

5.2 网络与超时的坑

插件所有功能都走远程请求,所以在网络受限或者代理环境复杂的场景下,表现会比本地工具差。跑测试偶尔等待几秒属于正常,如果频繁超时,建议把配置里的 Timeout 调大一点,我在一个网络不太稳定的项目里调大到接近二十秒,体验立刻正常了。

这里再多说一句,有些公司的办公网络会对测试提交接口做限制,表现为插件面板能加载,但跑测试总是失败。这种情况只能说明当前网络环境对这个接口不友好,和插件本身没关系,有条件的话换个网络环境就能确认。

5.3 模板与编码的坑

如果你的题目文件生成后编码有问题,中文描述全变乱码,大概率是 IDEA 全局或项目编码没统一。去 Settings 的 Editor -> File Encodings 里把 Global Encoding 和 Project Encoding 都设置为 UTF-8,再重新打开题目文件,基本就好了。

模板相关的坑主要体现在两类:一类是有人把文件名改成了包含空格或者中文特殊符号的格式,结果生成类名不规范,提交编译时类名对不上;另一类是自定义模板时不小心把提交标记写到模板里了,导致每道题都带错标记。我的建议是刚开始别折腾模板,默认配置就够用,等刷了五十道题你自然知道自己想要什么格式,再改也不迟。

5.4 关于提交标记的最后强调

我想再强调一遍提交标记的重要性。有的朋友为了在本地测试方便,会在生成的类里加一个带 main 方法的内部类,或者写几个测试辅助方法,这些都是合法的。但你加的时候要关心这些代码到底会不会被一起提交。合法做法是把辅助方法放在submit region标记内部,把 main 方法留在标记外面。如果你发现提交上去的代码里多了奇怪的东西,先检查标记是不是被你不小心挪了位置。

6. 几个让我刷题效率明显提升的习惯

6.1 自定义模板统一代码风格

用顺手之后我配置了一套自己的代码模板,主要改了几个点:生成文件的 package 路径统一到自己的包名,注释头里加上作者和创建时间,方法签名不变但类名保持题目英文名。这样刷到两三百题之后,本地代码库看起来完全像一个规范的开源项目,复习的时候非常舒服。

这个模板功能的存在本身也说明插件作者考虑得比大多数用户预期得周全。你如果也想改,先看看模板变量里支持哪些占位符,通常题号、标题、英文标题、代码块、问题描述都可以引用。改完记得重新打开一道题试试效果,别在自己已经在刷的题目上直接改,那样会产生文件命名冲突。

6.2 刷题仓库用 Git 打理

刷题代码是一笔资产,这句话我越来越有体会。我把 Temp Dir 指到了本地一个独立的刷题仓库里,每次提交通过后,连同那几句思路注释一起 commit,一天两道题就是两个 commit。到了面试前突击阶段,直接翻这个仓库按 Tag 或者按目录复习,比在网站上翻提交历史要直观太多。

用 Git 还有一个额外好处:你可以放心大胆地在题目文件里做实验,改乱了大不了回滚。这一点在网页编辑器里是完全不可能的,也是我用本地刷题方式之后再也没回去的主要原因。

6.3 每天固定两题的节奏

最后一件事其实和插件无关,但配合起来很有效:每天固定一个时间段打开 IDEA,固定刷两道题,一道复习昨天的旧题重做一遍,一道做新题。LeetCode Editor 让这个过程变得很快,打开面板、搜索、双击、写码、测试、提交,全套流程在五到十分钟内就能进入状态。我现在已经不太在意每天到底刷了几道,反而更在意每一道题提交之后有没有留下足够的思考痕迹,插件的本地文件机制恰好很自然地承载了这件事。

刷题工具本身不改变刷题效果,但一个顺手的工具确实能扫清很多环境上的阻力。如果你还在浏览器和 IDE 之间来回折腾,不妨花十分钟把 LeetCode Editor 装起来,配置好账号,拿一道简单题完整跑一遍流程。等你提交通过看到那个绿色对勾的时候,大概率就明白为什么这个插件能在一个系列里排到第 112 篇还被我反复推荐了。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进