面试题手册

梳理高频技术问题,帮助你按主题复习和查漏补缺。

服务端阅读 05月27日 14:00

Vim 有哪几种模式?怎么切换?

打开 Vim 第一件事:搞懂模式第一次用 Vim 的人几乎都会遇到同一个问题:明明在敲键盘,屏幕上怎么什么都没出现?原因很简单——Vim 不是你用过的那种编辑器,它有模式。在错误的模式下按键,Vim 不会乖乖输入文字,而是执行命令。这个设计乍看反直觉,但一旦习惯,编辑效率会远超普通编辑器。Vim 的核心思路是:不同的任务用不同的模式。浏览代码、输入文字、选择区域、执行命令——各有专属模式,按键含义随模式切换而改变。下面逐个说清楚。普通模式(Normal Mode)普通模式是 Vim 的默认状态。打开文件后你就处在这个模式里,从任何其他模式按 Esc 也能回到这里。在普通模式下,键盘上的每个键都是一个命令,而不是要输入的字符:h j k l — 左、下、上、右移动光标x — 删除光标下的字符dd — 删除整行yy — 复制整行p — 粘贴u — 撤销. — 重复上一次操作普通模式是你待得最久的地方。Vim 的哲学是"浏览多于输入",大部分时间你其实在阅读和导航,偶尔才需要打字。所以普通模式被设为默认,而不是插入模式。进入方式:启动 Vim 自动进入;任意模式按 Esc 或 Ctrl+[ 返回。插入模式(Insert Mode)这才是"像正常编辑器"的模式——你按什么键,屏幕上就出现什么字符。Vim 窗口左下角会显示 -- INSERT -- 提示你当前在插入模式。进入插入模式有好几种方式,区别在于光标落点:| 按键 | 效果 ||------|------|| i | 在光标前插入 || a | 在光标后插入 || I | 在行首(第一个非空字符前)插入 || A | 在行尾插入 || o | 在当前行下方新开一行并插入 || O | 在当前行上方新开一行并插入 || s | 删除光标下字符并进入插入 |实际使用中,i、a、o、A 四个用得最多。A 特别好用——想在行尾追加内容,一个键到位,不用先移光标再按 i。退出方式:按 Esc 或 Ctrl+[ 回到普通模式。可视模式(Visual Mode)可视模式用来选择文本,相当于用鼠标拖选,但效率更高。进入后左下角显示 -- VISUAL --。三种可视模式各有用途:v — 字符可视模式,逐字符选择,适合选中几个词V — 行可视模式,整行整行地选,适合操作连续多行Ctrl+v — 块可视模式,矩形选择,批量缩进、批量加注释时非常好用选中之后可以紧跟操作:d 删除、y 复制、> 缩进、< 反缩进、: 对选中区域执行命令。块可视模式有一个经典用法:批量注释。Ctrl+v 选中多行行首,按 I 输入 // 或 #,再按 Esc,选中的行会同时加上注释符号。退出方式:按 Esc,或再按一次 v/V/Ctrl+v。命令行模式(Command-Line Mode)在普通模式下按 :(冒号)进入命令行模式,光标跳到屏幕最底部,等待你输入命令。这个模式用于执行保存、退出、替换、设置选项等操作。常用命令::w — 保存:q — 退出:wq 或 :x — 保存并退出:q! — 强制退出不保存:%s/old/new/g — 全文替换:set number — 显示行号:!ls — 执行外部 shell 命令(这里是查看目录)命令输入完按回车执行,执行后自动回到普通模式。如果不想执行,按 Esc 取消。除了 :,按 / 进入搜索也是一种命令行模式,输入关键词后回车即可跳转匹配位置,按 n 跳到下一个,N 跳到上一个。替换模式(Replace Mode)替换模式不像前面四种那么常被提起,但在特定场景下很实用。进入后左下角显示 -- REPLACE --。R — 进入替换模式,你输入的每个字符会覆盖光标位置的现有字符,就像很多编辑器里的 Insert 键切换到覆盖模式一样r — 单次替换,替换光标下的一个字符后自动回到普通模式r 比 R 用得更频繁。比如把一个字母改掉,r 一个键搞定,不用先进插入模式再删再输。还有一种虚拟替换模式 gR,区别在于 Tab 键的处理——R 会把 Tab 当作一个字符覆盖,gR 则保持 Tab 的对齐逻辑不变。日常用得不多,知道有这回事就行。退出方式:按 Esc 回到普通模式。模式切换一览把上面的关系画出来就是:普通模式是枢纽,所有模式都通过 Esc 回到普通模式,再从普通模式进入其他模式。普通模式 ←Esc← 插入模式 (i/a/o...) ↓↑ ↓Esc →→ : → 命令行模式 ↓↑ →→ v/V/Ctrl+v → 可视模式 ↓↑ →→ R → 替换模式一个实用建议:如果你不确定当前在什么模式,连按两下 Esc,肯定回到普通模式。养成这个习惯,比记住所有快捷键都管用。从模式思维开始Vim 的模式系统不是负担,而是它高效的根本原因。普通模式让导航和编辑共用键盘,不用频繁碰鼠标;插入模式专注输入;可视模式批量操作;命令行模式处理全局事务;替换模式精确覆盖。搞清楚每种模式做什么、怎么进怎么出,剩下的就是肌肉记忆的事了。打开终端,输入 vimtutor,花三十分钟走一遍内置教程,比看十篇文章都管用。
服务端阅读 05月27日 14:00

Vim 常用插件有哪些?怎么安装和管理?

为什么要折腾 Vim 插件Vim 本身已经是个够用的编辑器,但离「用得舒服」还差一截——没有文件树、没有智能补全、没有 Git 状态提示,每次切文件都得 :e 手敲路径。装上几个关键插件之后,Vim 的体验会发生质变。这篇文章不会给你列几十个插件让你挑花眼,只讲那些真正经得起时间考验的工具,以及怎么装、怎么管。先选一个插件管理器装插件之前,得先搞定插件管理器。主流选择有三个:vim-plug — 目前最流行的选择。配置语法简洁,并行安装速度快,支持懒加载。一个 Plug 'author/repo' 就完事,入门成本最低。安装只需要一行 curl:curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vimVundle — 老牌管理器,语法和 vim-plug 类似(Plugin 'author/repo'),功能够用但已经不怎么更新了。如果你接手的老项目 .vimrc 里用的 Vundle,能看懂就行,新项目不建议再用。dein.vim — Shougo 开发的新一代管理器,异步安装、细粒度懒加载、hooks 回调,功能最强。代价是配置比 vim-plug 复杂不少,适合对启动速度有强迫症的用户。要求 Vim 8.0+ 或 Neovim。实际建议:大多数人选 vim-plug 就够了。它的 plug#begin() / plug#end() 结构清晰,:PlugInstall、:PlugUpdate、:PlugClean 三条命令覆盖日常操作。文件浏览:NERDTreeNERDTree 是 Vim 生态里最经典的文件浏览器,打开后左侧会出现一棵目录树,可以用键盘上下导航、回车打开文件。装了它就不用在终端和 Vim 之间来回切了。安装:Plug 'preservim/nerdtree'常用快捷键得配一下,不然每次手动敲 :NERDTreeToggle 太痛苦:nnoremap <C-n> :NERDTreeToggle<CR>" 打开 Vim 时自动显示 NERDTreeautocmd VimEnter * NERDTree" 关闭最后一个文件时自动关闭 NERDTreeautocmd BufEnter * if tabpagenr('$') == 1 && winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | quit | endifNERDTree 的核心操作就几个:o 打开文件/展开目录,t 在新标签页打开,i 水平分屏打开,s 垂直分屏打开,m 打开菜单(新建/删除/重命名文件)。按 ? 可以看完整帮助。如果你觉得 NERDTree 太重,可以试试 vim-dirvish 或 netrw(Vim 自带),但功能上差距明显。模糊搜索:fzffzf 是目前最快的模糊搜索工具,没有之一。它用 C 写的,比纯 VimScript 实现的 ctrlp 快好几个量级,文件多的时候体感差距非常大。安装需要两个部分:Plug 'junegunn/fzf', { 'do': './install --all' }Plug 'junegunn/fzf.vim'fzf 是核心引擎,fzf.vim 是 Vim 集成层。装完后常用的命令::Files — 模糊搜索文件:GFiles — 只搜 Git 跟踪的文件:Buffers — 在已打开的 buffer 里搜索:Rg 或 :Ag — 全局内容搜索(需要安装 ripgrep 或 silver-searcher)建议配一下快捷键:nnoremap <C-p> :Files<CR>nnoremap <leader>b :Buffers<CR>nnoremap <leader>g :Rg<CR>fzf 的搜索窗口样式也可以调:let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } }如果你之前用 ctrlp,迁移到 fzf 几乎无痛,搜索速度的提升会让你立刻觉得值。智能补全:coc.nvimcoc.nvim 是 Vim 生态里最接近 VS Code 补全体验的插件,基于 Language Server Protocol(LSP),支持跳转到定义、查找引用、重命名、自动补全、诊断提示等。它基本上把以前需要装五六个插件才能凑齐的功能统一了。安装:Plug 'neoclide/coc.nvim', {'branch': 'release'}装完插件本身还不够,还得装对应语言的扩展。在 Vim 里执行::CocInstall coc-tsserver " JavaScript/TypeScript:CocInstall coc-pyright " Python:CocInstall coc-go " Go:CocInstall coc-rust-analyzer " Rust:CocInstall coc-json " JSON:CocInstall coc-html " HTML:CocInstall coc-css " CSS关键快捷键配置:nmap <silent> gd <Plug>(coc-definition)nmap <silent> gy <Plug>(coc-type-definition)nmap <silent> gi <Plug>(coc-implementation)nmap <silent> gr <Plug>(coc-references)nmap <leader>rn <Plug>(coc-rename)gd 跳转到定义,gr 查找引用,n 重命名符号——这三个大概是用得最频繁的操作。coc.nvim 需要 Node.js 环境(>= 14),如果机器上没装 Node,这一步会报错。用 nvm 或系统包管理器装一个就行。状态栏:vim-airline默认的 Vim 状态栏只显示文件名和行列号,信息量很少。vim-airline 给状态栏加上了当前模式、Git 分支、文件类型、编码、语法检查状态等信息,底部一行就能掌握全局。Plug 'vim-airline/vim-airline'Plug 'vim-airline/vim-airline-themes'如果你也装了 fugitive 和 coc.nvim,airline 会自动显示 Git 分支名和 LSP 诊断数量,不需要额外配置。换个主题可以让状态栏更好看:let g:airline_theme = 'onedark'如果觉得 airline 依赖太多,轻量替代是 lightline.vim,功能少一些但启动更快。Git 集成:vim-fugitive + vim-gitgutter两个插件各管一摊:fugitive 负责在 Vim 里执行 Git 操作,gitgutter 负责在行号旁显示改动标记。vim-fugitive 把 Git 命令搬进了 Vim:Plug 'tpope/vim-fugitive'常用命令::Gstatus 查看状态,:Gwrite 相当于 git add,:Gcommit 提交,:Gdiff 看差异,:Gblame 看每行的提交记录。用熟了之后几乎不需要切到终端操作 Git。vim-gitgutter 在行号左侧实时标记增删改:Plug 'airblade/vim-gitgutter'+ 号表示新增行,- 号表示删除行,~ 号表示修改行。可以配合 ]h 和 [h 在改动块之间跳转。如果觉得实时检测太耗性能,可以设个间隔:let g:gitgutter_realtime = 0let g:gitgutter_eager = 0一个能用的完整配置把上面这些组合起来,一个实用的 .vimrc 长这样:" === 插件管理 ===call plug#begin('~/.vim/plugged')" 文件浏览Plug 'preservim/nerdtree'" 模糊搜索Plug 'junegunn/fzf', { 'do': './install --all' }Plug 'junegunn/fzf.vim'" 智能补全Plug 'neoclide/coc.nvim', {'branch': 'release'}" 状态栏Plug 'vim-airline/vim-airline'Plug 'vim-airline/vim-airline-themes'" GitPlug 'tpope/vim-fugitive'Plug 'airblade/vim-gitgutter'call plug#end()" === 通用设置 ===set numberset relativenumberset tabstop=4set shiftwidth=4set expandtabset hiddenset updatetime=100" === NERDTree ===nnoremap <C-n> :NERDTreeToggle<CR>" === fzf ===nnoremap <C-p> :Files<CR>nnoremap <leader>b :Buffers<CR>let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6 } }" === coc.nvim ===nmap <silent> gd <Plug>(coc-definition)nmap <silent> gr <Plug>(coc-references)nmap <leader>rn <Plug>(coc-rename)" === airline ===let g:airline_theme = 'onedark'" === gitgutter ===set signcolumn=yes写完之后打开 Vim,执行 :PlugInstall,等安装完重启,就有一个堪比轻量 IDE 的编辑环境了。几点避坑提醒插件不是越多越好。每多一个插件,启动时间就多一点,出冲突的概率也大一点。上面这套组合已经覆盖了日常开发的绝大多数场景,先跑起来再说。coc.nvim 是这套配置里最重的插件,首次打开会慢一两秒。如果受不了,可以换成 vim-lsp + asyncomplete 的组合,轻量但配置更繁琐。fzf 的 :Rg 搜索需要系统里装了 ripgrep。macOS 用 brew install ripgrep,Ubuntu 用 apt install ripgrep。如果你在用 Neovim,可以考虑把 vim-plug 换成 Lua 原生的 lazy.nvim,但这篇文章聚焦 Vim,就不展开了。装好这六七个插件,日常写代码的效率会有明显提升。不用急着把所有插件都试一遍,先把这几个用熟,之后想加什么再加。
服务端阅读 05月27日 14:00

Vim 怎么分割窗口和管理标签页?

从单窗口到多窗口:为什么你需要分割用 Vim 写代码,最痛苦的事之一就是频繁切换文件。改完配置切回源码,看完测试切回实现,来回几次就晕了。其实 Vim 早就提供了窗口分割和标签页功能,只是很多人习惯了单窗口操作,根本没碰过这些特性。理解 Vim 的窗口模型有一个关键前提:窗口不是文件。Vim 里真正存文件内容的是 buffer(缓冲区),窗口只是"查看 buffer 的视口"。同一个 buffer 可以被多个窗口同时显示,一个标签页里可以放多个窗口,每个窗口显示不同的 buffer。这跟浏览器标签页的概念不一样——Vim 的 tab 是"窗口布局的容器",不是"文件的容器"。窗口分割:左右对照,上下对比水平分割输入 :split 或简写 :sp,当前窗口会从中间水平切开,上下各显示一份当前文件。光标停在新窗口里,可以直接编辑。如果想分割后打开另一个文件,加文件名即可::sp config.yaml快捷键 Ctrl+w s 效果相同,不用敲命令行。垂直分割需要左右并排时用 :vsplit 或 :vsp,窗口会纵向一分为二。同样支持带文件名参数::vsp main.go快捷键是 Ctrl+w v。新建空窗口:new 创建一个水平分割的空窗口,:vnew 创建垂直分割的空窗口。适合临时记笔记或粘贴内容。窗口切换:快速跳转不迷路分割出一堆窗口后,你得能在它们之间来回跳。| 快捷键 | 作用 ||--------|------|| Ctrl+w h | 跳到左边窗口 || Ctrl+w j | 跳到下边窗口 || Ctrl+w k | 跳到上边窗口 || Ctrl+w l | 跳到右边窗口 || Ctrl+w w | 循环切换窗口 || Ctrl+w p | 跳到上一个访问的窗口 |方向键也可以用:Ctrl+w 加方向键。但 h/j/k/l 更符合 Vim 习惯,手不用离开主键区。窗口大小调整:拖不动就命令来鼠标拖动调整大小在某些终端里能用,但命令行方式更精确。逐步调整:Ctrl+w + 增加高度Ctrl+w - 减少高度Ctrl+w > 增加宽度Ctrl+w < 减少宽度加数字前缀可以一次调多行,比如 5 Ctrl+w + 把当前窗口增高 5 行。快速调整:Ctrl+w = 所有窗口等宽等高Ctrl+w _ 当前窗口最大化高度Ctrl+w | 当前窗口最大化宽度Ctrl+w _ 和 Ctrl+w | 也可以加数字前缀指定精确行数或列数,比如 20 Ctrl+w _ 把窗口高度设为 20 行。关闭与保留窗口:close 或 :clo:关闭当前窗口(如果这是最后一个窗口则不会关闭)Ctrl+w c:同上:only 或 :on:只保留当前窗口,关闭其他所有窗口Ctrl+w o:同上注意 :close 和 :q 的区别:如果窗口里有未保存的修改,:close 会拒绝关闭,而 :q! 会直接丢弃。用 :close 更安全。窗口移动:重新排列布局有时候分割出来的位置不对,想换个方向。Ctrl+w H:把当前窗口移到最左边(变成全高垂直分割)Ctrl+w J:把当前窗口移到最下边(变成全宽水平分割)Ctrl+w K:把当前窗口移到最上边Ctrl+w L:把当前窗口移到最右边Ctrl+w T:把当前窗口移到一个新标签页Ctrl+w r 可以旋转窗口位置,Ctrl+w R 反向旋转。这些大写命令是改变窗口布局的利器。标签页:另一种组织方式标签页适合管理不同的"工作区"。比如一个标签页放前端代码的分割布局,另一个放后端代码的分割布局,互相不干扰。创建标签页:tabedit path/to/file " 在新标签页打开文件:tabnew " 打开一个空白标签页:tab split " 把当前窗口内容放到新标签页从命令行启动时也可以直接用标签页模式:vim -p file1.rs file2.rs file3.rs切换标签页gt:下一个标签页gT:上一个标签页Ngt:跳到第 N 个标签页(比如 2gt 跳到第二个):tabn:下一个(next):tabp:上一个(previous):tabfirst 或 :tabr:跳到第一个:tablast:跳到最后一个gt 和 gT 是最常用的,两个字母就能切换,效率很高。关闭标签页:tabclose 或 :tabc:关闭当前标签页:tabonly 或 :tabo:关闭其他所有标签页关闭标签页会同时关掉里面的所有窗口,但如果 buffer 有未保存的修改,Vim 会提示你。标签页排序:tabm 0:移到第一个位置:tabm:移到最后一个位置:tabm 2:移到第三个位置(索引从 0 开始)查看当前所有标签页用 :tabs,会列出每个标签页里的窗口和 buffer 信息。Buffer:窗口和标签页的底层聊窗口和标签页不能不提 buffer,因为它们本质上都是 buffer 的不同展示方式。:ls:列出所有 buffer:b filename:按文件名切换 buffer(支持模糊匹配):bn:下一个 buffer:bp:上一个 bufferCtrl+^:在上一个 buffer 和当前 buffer 之间快速切换很多老 Vim 用户其实不怎么用标签页,他们更习惯用 buffer 切换。:b 加文件名的一部分就能跳过去,配合 :ls 查看列表,比标签页更轻量。推荐配置把这些加到 .vimrc 里,窗口操作会顺手很多:" 等号分割用 leader 键触发nnoremap <leader>w= <C-w>=nnoremap <leader>wo <C-w>onnoremap <leader>wc <C-w>c" 标签页切换用 Alt+h/lnnoremap <M-l> gtnnoremap <M-h> gT" 垂直分割快捷键nnoremap <leader>wv <C-w>vnnoremap <leader>ws <C-w>s这些不是必须的,但能减少按键次数。如果你用 Neovim 或加了插件,很多窗口管理操作已经有更高级的方案(比如 telescope 的 buffer 列表、bufferline 的标签页美化),底层逻辑还是这一套。实战场景对比修改: 写完 API 接口,想对照路由定义检查参数,:vsp routes.go 垂直分割,左边看接口,右边看路由。重构追踪: 改了一个函数签名,要同时改调用方和测试,水平分割三窗口:src、caller、test,改一处扫一眼其他两处。多项目并行: 一个标签页放当前功能的代码分割布局,另一个标签页放需要参考的第三方库源码,gt 一键切换上下文,比来回切换文件高效得多。Vim 的窗口和标签页功能不花哨,但足够实用。花几分钟记住分割、切换、调整大小这几个核心操作,编辑效率会有明显提升。不需要一步到位配置成 IDE 那样的多面板布局,先从 :sp 和 :vsp 开始用就行。
服务端阅读 05月27日 14:00

Vim 有哪些快速移动命令?光标跳转怎么操作?

Vim 的移动命令比你想象的多得多很多人学 Vim 的第一步是记住 hjkl,然后就在这四个键上原地踏步。其实 hjkl 只是 Vim 移动体系里最慢的一层——当你学会更高级的移动方式后,会发现自己几乎不再需要逐字符挪动光标。下面按粒度从细到粗,把 Vim 的快速移动命令梳理一遍。字符级:行内的精确打击行内移动是最高频的操作,掌握这几个命令能省大量按键:f{char} — 跳到当前行下一个出现 {char} 的位置,光标落在字符上F{char} — 反向搜索,跳到当前行上一个 {char}t{char} — 和 f 类似,但光标停在目标字符前一个位置T{char} — 反向的 t; — 重复上一次 f/F/t/T 查找, — 反向重复上一次 f/F/t/T 查找举个例子,光标在行首,行内容是 const result = calculate(x, y),按 f= 直接跳到等号,再按 ; 可以继续找下一个等号。t) 则会跳到右括号的前一个字符——配合 d 操作符删除到括号前非常顺手。单词级:以语义单位跳转逐字符移动太慢,逐单词才是日常节奏:w / W — 跳到下一个单词开头(小写以标点为分隔,大写只认空格)b / B — 跳到上一个单词开头e / E — 跳到当前/下一个单词末尾ge / gE — 跳到上一个单词末尾小写和大写的区别在于"单词"的定义:w 把 foo-bar 视为三个单词(foo、-、bar),而 W 视为一个。写代码时大写往往更实用,因为变量名里经常有连字符和点号。加数字前缀可以倍增:3w 向后跳三个单词。行级:一秒到行首行尾0 — 跳到行首(第一列)^ — 跳到行首第一个非空白字符$ — 跳到行尾g_ — 跳到行尾最后一个非空白字符实际编码中 ^ 比 0 更常用,因为代码行首通常有缩进。g_ 则在处理行尾注释或多余空格时很方便。段落与句子:大块跳转{ — 跳到上一个空行(段落开头)} — 跳到下一个空行( — 跳到上一句开头) — 跳到下一句开头在代码里 { 和 } 非常实用,因为函数之间通常有空行分隔。按 } 就能快速跳到下一个函数。屏幕级:视野内的快速定位H — 跳到屏幕顶部第一行M — 跳到屏幕中间一行L — 跳到屏幕底部最后一行zt — 当前行滚到屏幕顶部zz — 当前行滚到屏幕中间zb — 当前行滚到屏幕底部zz 是被严重低估的命令——当你编辑了一行代码想让它在屏幕中间显示时,按 zz 比翻页再移光标快得多。翻页:半页比整页更实用Ctrl+d — 向下翻半页Ctrl+u — 向上翻半页Ctrl+f — 向下翻一整页Ctrl+b — 向上翻一整页新手容易习惯整页翻,但半页翻(Ctrl+d / Ctrl+u)更好用——翻完之后眼睛不需要重新定位,因为上下文还有一半留在屏幕上。文件级:跳到任意行gg — 跳到文件第一行G — 跳到文件最后一行{n}G 或 :{n} — 跳到第 n 行配合相对行号(set relativenumber),可以一眼看出目标行与当前行的距离,直接 {n}j 或 {n}k 跳过去,比输入行号更快。搜索:最快的"我想去哪就去哪"/pattern — 向下搜索?pattern — 向上搜索n / N — 跳到下一个/上一个匹配* — 向下搜索光标下的单词# — 向上搜索光标下的单词* 是日常高频操作——把光标放在一个变量名上按 *,立刻跳到下一个使用该变量的位置,比手动输入 /variableName 快得多。搜索还能和操作符组合:d/pattern 删除到下一个匹配处,c/pattern 修改到下一个匹配处。括号匹配:在代码结构间穿梭% — 在匹配的括号之间跳转(支持 ()、[]、{})光标在 ( 上按 % 跳到对应的 ),再按一次跳回来。配合 v% 可以选中整个括号内的内容。标记:书签式的瞬移m{a-z} — 设置局部标记(当前文件内有效)m{A-Z} — 设置全局标记(跨文件有效)`{mark} — 跳到标记的精确位置'{mark} — 跳到标记所在行的行首标记适合在两个位置之间反复切换的场景。比如在函数定义和调用处各设一个标记,用 `a 和 `b 来回跳。跳转列表:Vim 内置的"后退/前进" `` — 跳回上一次跳转来的位置Ctrl+o — 在跳转列表中后退Ctrl+i — 在跳转列表中前进Vim 会自动记录你的跳转历史。无论你用 G、/、* 还是 :{n} 跳到别处,按 Ctrl+o 都能回到之前的位置。连续按可以一路退回去,Ctrl+i 则反方向前进。这对阅读大型代码库特别有用。gd 和 gD:跳到定义gd — 跳到光标下变量的局部定义gD — 跳到光标下变量的全局定义虽然不如 LSP 的"跳转到定义"精确,但在没有语言服务器的情况下,gd 已经能覆盖大部分场景。数字前缀:一切移动命令的倍增器前面提到的几乎所有移动命令都能加数字前缀:5j — 向下 5 行3w — 向后 3 个单词2f= — 跳到第 2 个等号10Ctrl+d — 向下翻 10 行(而非半页)这是 Vim 的核心设计思路——移动命令是名词,数字是量词,操作符是动词,组合出无限可能。如果你目前还主要靠 hjkl 和方向键移动,建议先从 w/b、f/t、Ctrl+d/Ctrl+u 这三组开始练。它们覆盖了最高频的移动场景,熟练之后编辑速度会有明显的跃升。其他的命令用到了再查,不用刻意背——Vim 的学习本来就是用出来的,不是背出来的。