关于刷题环境的看法与选择
今天在准备机试,拿起很久没刷的算法题 (上次刷题还是大一刷洛谷) ,除了考虑刷哪一套题单,要考虑的就是使用什么语言、什么环境来刷。
2023年5月更新:
刷了一个多月题后我的感受发生了变化,其实用什么语言不重要,相反的,如果你想要快速上手一门语言的基本特性,你就用它来刷题就对了。
刷题环境的选择标准
由于线上环境与本地环境有较大区别,而面向机试的刷题练习应该尽量做到与线上环境保持一致 ,因此我提出了对本地环境的以下几点基本要求:
- 尽量使用 文本编辑器+单文件(脚本) 的方式而 非IDE+项目 的模式,方便管理多道题目
- 编译运行过程尽量简单,且支持单步调试
- 语法简单易上手
(刷题就不要想,有完善的轮子borrow
的事情了)(谁也不想用C手搓堆吧) 语言运行速度不拖后腿,这点其实不太重要,因为大多只看复杂度而不看绝对时间- 环境本身不应提供过多辅助功能(如Copilot),有些在线环境甚至不提供代码提示
基于上述的基本标准,我们再进一步地细化一些标准,优先级从上到下递减:
- 完善的轮子,如容器库、基础数据类操作方法等
- 单文件结构体系(或脚本语言),不依赖项目(刷题几乎不存在项目复用的需求,除非极少数题目共享数据结构需要多文件模块化)
- 函数为一等公民,而不必用类去包裹
- 简便的调试,清晰的异常处理信息
性能够用,贴近底层,有更多优化空间(不打榜的话其实没有需求)
刷题环境的推荐
根据我们上面提出的规则,根据满足的规则多少,我们将按优先级先后排列主流刷题环境,并依次叙述如何快速配置(均搭配Windows下的VS Code编辑器):
- C++ 11: 满足1、2、3、5(4部分符合)
- JS: 满足1、2、3、4(不包含TS,TS配置太麻烦了,不能开箱即用)
- Python:满足1、2、3、4
(其实个人感觉Python比JS更好,但由于我讨厌Python的缩进所以放到后面) - C# Script:满足1、2、3(部分4,且性能有些一言难尽)
- Java:满足1、4
(如果不是后端需求大我真的都不想推荐)
VS Code 中的相关插件就不再推荐,自己搜索官方插件安装即可。
C++ 11
先抛开C++贴近底层的性能优势不谈(单纯刷题的话并无太大优势),由于C语言几乎是科班必修,C++完全可以当成C+STL来用,对初学者而言上手难度极低。
与此同时,在使用C++、看别人题解的同时也可以学习一些比较现代的C++语法(亲测洛谷、力扣和牛客都支持C++11),如auto
迭代器、lambda
表达式等。除此之外,C++的上限还很高,换句话说就是C++允许你去抠每个细节的性能,如果你觉得官方库的性能不尽人意你甚至可以自己写来超过官方库(如果你够牛的话,比如超过不开O2的STL)。
除此之外,C++还是CSP的官方赛事语言(不喜欢Java的同学们有福啦),虽然只允许你使用 Dev-CPP 作为环境。
环境配置(WSL2)
做C++开发的话,个人还是推荐在Linux环境下,WSL2 Ubuntu就是不错的选择。一方面可以避免Windows下C++安装配环境变量很麻烦或者被迫用 msbuild 的情况,一方面还可以练一练 Linux 小技巧,一石二鸟,何乐而不为呢?
首先安装WSL2 (这部分略),安装完成后安装C/C++套件:
1 | sudo apt-get install build-essential gdb |
如果成功打印了版本说明安装成功!
接着配置 VS Code 中的 WSL 开发环境,包括 launch.json
和 tasks.json
两部分,详见:使用vs code和wsl搭建C/C++开发环境_wsl c++ 。(偷懒了,以后会补充的)
环境配置(Windows)
如果你是一个坚定的 Windows 党,你也可以选择手动在 Windows 上配置 mingw-w64 套件来安装 g++(总之就是不推荐在VS以外使用MSBuild)
具体步骤如下:
- 在mingw-w64官网 找到一个Windows的预编译包(一般是x86-64),我个人用的是llvm-mingw (github.com) (如果你上不去或者下载不了,建议先把梯子搞定了,而不要去找网盘或者镜像源,学会使用国际互联网是在中国搞开发的第一步)
- 下载,解压,放到你喜欢的目录下面,比如我的目录是
c:/mingw
,注意看里面应该有一个bin/
目录,而里面就有 gcc.exe 和 g++.exe 等等 - 把解压的目录添加到环境变量
- 添加完了在终端里试试
g++ -v
,如果显示了版本就说明安装成功。
后续配置VSCode的过程和上面几乎相同。
C++的弊端
- C++的语法非常的不优雅,相对于C#和Java来说,一堆
::
和下划线实在不是很好看 - C++的字符串处理不太行,很多功能如
split
等都需要手写 - C++的报错信息很不友好,堆分配对象的Debug体验也很不好(指针就只给你显示它自己解引用的值)
- VSCode配置相比JS和Python这样的脚本语言来说麻烦很多
但是没办法,你就是得会、得用C++。
JS
虽然我个人秉承着能用TS就不用JS的理念,但这也只是工程上。刷题的时候强调的就是一个开箱即用,而TS还要转译、配置无疑太过麻烦了,而且引入类型系统对刷题这个代码量其实没有太多的好处。
JS是动态类型的、解释型的脚本语言,语法和Java很像,而且也可以直接编写顶层函数,也可以使用ES6后的现代语法和容器等等,而且它的配置相比C++来说简单太多,VS Code这种本就为前端而生的编辑器对JS和Node的支持可以说是开箱即用。
之前我还在担心JS的动态类型和奇怪特性会影响刷题,但现在看来完全是我多想了,用JS刷题对于前端er和Java开发者都是很爽的(特别是对C不熟悉的人)。
配置过程
- 安装 Node.JS (16或18都可以),过程比较简单,下一步即可
- 运行
node --version
检查安装情况 - 直接在 VS Code 里开写,调试配置会自动生成(Run Code也可以直接运行)
Python
Python 作为数据科学常用的语言,也是动态的、解释型的,其实个人感觉刷题体验和JS应该是不相上下的。与JS不同的是,cpython的底层让Python更多作为其他语言的“前端”存在(如C++写的众多机器学习、科学计算库),像胶水一样黏合不同的语言,降低使用门槛。
但是刷题过程中几乎不用到这些第三方库,Python的生态优势就消散了不少,不过即使Python本身性能较弱,但面对刷题这样的“轻量级需求”还是绰绰有余的。
个人而言,Python令我最膈应的地方还是缩进语法了,我真的很难想象一个正经语言会用空白符作为有用的语义分割。
最后,我的评价是:该用还得用,如果你本来就对Python很熟,用就对了!
配置过程
- 安装 Python(Python的版本管理是很麻烦的,但是刷题不管)
- 检查环境变量,终端运行
python
- 直接在 VS Code 里开写,调试配置会自动生成(Run Code也可以直接运行)
C# Script
这里不再推荐传统C#项目,而是C# Script,什么是C# Script可以看看我的这篇文章。毕竟 C# Script(下文简称CSX)就是利用了顶层语句和隐式引用语法糖+REPL解释环境的C#环境,也就是说里面完完全全就是C#的语法和环境,只是变成了脚本语言的形式。
它最大的优势就是C#完备的轮子(各种容器、数据处理和LinQ),还有C#大量的语法糖降低了编写复杂度(如var
类型、隐式元组等),而这一切又以脚本的形式呈现出来(感觉就像 Python++),还支持单步调试。
它也有几点缺点,而且这些缺点还不小,所以排名才这么靠后:
- 性能问题:REPL环境天生性能更差,在线平台C#的性能表现也不尽人意,但是过关肯定没问题
- 大部分刷题环境不支持CSX,需要手动转换成类语法比较麻烦
具体配置的话还是参考我的另一篇文章:初探 C# Script - ChlorineC’s Blog
Java
个人感觉Java最大的槽点是擦除式泛型,但是这对刷题几乎没有影响。
Java 个人感觉最大的问题和 C# 这样的强OOP语言一样,是与项目深度绑定,但 C# Script 已经出了,所以现在只有 Java 一枝独秀了(谁让JS和Java不算是一门语言呢)。
如果你用着IDEA的话,那就直接用Java也没啥问题,否则个人感觉用VS Code去配Java还是有点麻烦的,具体配置过程这里就不再赘述。
至于老生常谈的GC和JVM调优这些问题,一方面对刷题根本没有影响,一方面新版本的JDK已经基本解决了这些问题(zGC和Native AOT)。
我本来以为Java和.NET性能应该是半斤八两的,毕竟个人体验下来在本地环境里.NET7其实会略快于Java11,但是刷题的实际成绩中Java大幅领先C# 10倍左右,时间复杂度直逼C++。
Benchmark
这里以搜索二维矩阵为例,以全部二分法在LeetCode的评测结果作为Benchmark测试各平台性能。
在线平台:LeetCode 2023/04/12
解题代码如下(以C#为例):
1 | public class Solution { |
最终相同代码在不同语言下得到的成绩如下:
【图坏了】
可以看到:
- C++发挥稳定,内存占用一如既往的独一档,但Java执行用时和其在一个水平上令人亮眼
- C#和Java作为带Runtime和GC的语言,内存占用在一个量级上
- C#不知道什么原因大幅落后于Java
- Python表现令人意外(也可能是C#令人太意外了),处于中规中矩的水平
个人的其他困惑
关于在线平台个人最大的不满还是运行环境的不透明性,你不能直观地知道当前运行环境的SDK版本,也不知道相关配置(有没有开启特定优化)。
其次是在线编译器的代码提示不完整,编译和Debug体验也不好,与本地环境脱节比较严重。
- 标题: 关于刷题环境的看法与选择
- 作者: ChlorineC
- 创建于 : 2023-04-12 08:00:00
- 更新于 : 2024-10-18 18:03:42
- 链接: https://chlorinec.top/2023/04/12/Development/what-is-best-leetcode-lang/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。