
我修好了我的博客——如何设计一个全新的博客框架
作者分享了个人博客框架迭代历程:从Hexo迁移到Astro的尝试,到发现Elog平台带来的启发,最终思考将Notion作为内容管理系统的新方案。文章重点描述了作者对博客系统的核心需求——解决创作同步问题,以及在探索NotionNext等解决方案过程中遇到的技术限制和思考。
本文讨论了刷题时选择编程语言和环境的标准,强调使用简单的文本编辑器和单文件脚本而非IDE。推荐的语言包括C++、JavaScript、Python、C# Script和Java,分别分析了它们的优缺点和配置过程。C++因其性能和现代语法被优先推荐,JavaScript和Python则因其易用性和灵活性受到青睐。文章还提到在线平台的环境不透明性和代码提示不足的问题。
今天在准备机试,拿起很久没刷的算法题 (上次刷题还是大一刷洛谷) ,除了考虑刷哪一套题单,要考虑的就是使用什么语言、什么环境来刷。
2023年5月更新:
经过一个多月的刷题,我的看法有了转变。实际上,使用哪种语言并不是关键。相反,如果你想迅速掌握一门语言的基本特性,用它来刷题就是最佳选择。
由于线上环境与本地环境有较大区别,而面向机试的刷题练习应该尽量做到与线上环境保持一致 ,因此我提出了对本地环境的以下几点基本要求:
borrow
基于上述的基本标准,我们再进一步地细化一些标准,优先级从上到下递减:
根据我们上面提出的规则,根据满足的规则多少,我们将按优先级先后排列主流刷题环境,并依次叙述如何快速配置(均搭配Windows下的VS Code编辑器):
VS Code 中的相关插件就不再推荐,自己搜索官方插件安装即可。
先抛开C++贴近底层的性能优势不谈(单纯刷题的话并无太大优势),由于C语言几乎是科班必修,C++完全可以当成C+STL来用,对初学者而言上手难度极低。
与此同时,在使用C++、看别人题解的同时也可以学习一些比较现代的C++语法(亲测洛谷、力扣和牛客都支持C++11),如auto
迭代器、lambda
表达式等。除此之外,C++的上限还很高,换句话说就是C++允许你去抠每个细节的性能,如果你觉得官方库的性能不尽人意你甚至可以自己写来超过官方库(如果你够牛的话,比如超过不开O2的STL)。
除此之外,C++还是CSP的官方赛事语言~~(不喜欢Java的同学们有福啦)~~,虽然只允许你使用 Dev-CPP 作为环境。
做C++开发的话,个人还是推荐在Linux环境下,WSL2 Ubuntu就是不错的选择。一方面可以避免Windows下C++安装配环境变量很麻烦或者被迫用 msbuild 的情况,一方面还可以练一练 Linux 小技巧,一石二鸟,何乐而不为呢?
首先安装WSL2(这部分略),安装完成后安装C/C++套件:
sudo apt-get install build-essential gdb
# 安装完成后检查
g++ -v
gdb -v
如果成功打印了版本说明安装成功!
接着配置 VS Code 中的 WSL 开发环境,包括 launch.json
和 tasks.json
两部分,详见:使用vs code和wsl搭建C/C++开发环境_wsl c++。(偷懒了,以后会补充的)
如果你是一个坚定的 Windows 党,你也可以选择手动在 Windows 上配置 mingw-w64 套件来安装 g++(总之就是不推荐在VS以外使用MSBuild)
具体步骤如下:
c:/mingw
,注意看里面应该有一个 bin/
目录,而里面就有 gcc.exe 和 g++.exe 等等g++ -v
,如果显示了版本就说明安装成功。后续配置VSCode的过程和上面几乎相同。
::
和下划线实在不是很好看split
等都需要手写但是没办法,你就是得会、得用C++。
虽然我个人秉承着能用TS就不用JS的理念,但这也只是工程上。刷题的时候强调的就是一个开箱即用,而TS还要转译、配置无疑太过麻烦了,而且引入类型系统对刷题这个代码量其实没有太多的好处。
JS是动态类型的、解释型的脚本语言,语法和Java很像,而且也可以直接编写顶层函数,也可以使用ES6后的现代语法和容器等等,而且它的配置相比C++来说简单太多,VS Code这种本就为前端而生的编辑器对JS和Node的支持可以说是开箱即用。
之前我还在担心JS的动态类型和奇怪特性会影响刷题,但现在看来完全是我多想了,用JS刷题对于前端er和Java开发者都是很爽的(特别是对C不熟悉的人)。
node --version
检查安装情况Python 作为数据科学常用的语言,也是动态的、解释型的,其实个人感觉刷题体验和JS应该是不相上下的。与JS不同的是,cpython的底层让Python更多作为其他语言的“前端”存在(如C++写的众多机器学习、科学计算库),像胶水一样黏合不同的语言,降低使用门槛。
但是刷题过程中几乎不用到这些第三方库,Python的生态优势就消散了不少,不过即使Python本身性能较弱,但面对刷题这样的“轻量级需求”还是绰绰有余的。
个人而言,Python令我最膈应的地方还是缩进语法了,我真的很难想象一个正经语言会用空白符作为有用的语义分割。
最后,我的评价是:该用还得用,如果你本来就对Python很熟,用就对了!
python
这里不再推荐传统C#项目,而是C# Script,什么是C# Script可以看看我的这篇文章。毕竟 C# Script(下文简称CSX)就是利用了顶层语句和隐式引用语法糖+REPL解释环境的C#环境,也就是说里面完完全全就是C#的语法和环境,只是变成了脚本语言的形式。
它最大的优势就是C#完备的轮子(各种容器、数据处理和LinQ),还有C#大量的语法糖降低了编写复杂度(如var
类型、隐式元组等),而这一切又以脚本的形式呈现出来(感觉就像 Python++),还支持单步调试。
它也有几点缺点,而且这些缺点还不小,所以排名才这么靠后:
具体配置的话还是参考我的另一篇文章:初探 C# Script - ChlorineC's Blog
个人感觉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++。
这里以搜索二维矩阵为例,以全部二分法在LeetCode的评测结果作为Benchmark测试各平台性能。
在线平台:LeetCode 2023/04/12
解题代码如下(以C#为例):
public class Solution {
public bool SearchMatrix(int[][] matrix, int target) {
if (matrix.Length == 0 || matrix[0].Length == 0) return false;
int begin, mid, end;
begin = mid = 0;
int dim1 = matrix.Length, dim2 = matrix[0].Length;
end = dim1 * dim2 -1;
while (begin < end) {
mid = (begin + end) / 2;
if (matrix[mid/dim2][mid%dim2] < target) begin = mid + 1;
else end = mid;
}
return matrix[begin/dim2][begin%dim2] == target;
}
}
最终相同代码在不同语言下得到的成绩如下:
【图坏了】
可以看到:
关于在线平台个人最大的不满还是运行环境的不透明性,你不能直观地知道当前运行环境的SDK版本,也不知道相关配置(有没有开启特定优化)。
其次是在线编译器的代码提示不完整,编译和Debug体验也不好,与本地环境脱节比较严重。
作者: ChlorineC
创建于: 2023-04-11 16:46:00
更新于: 2025-01-05 09:03:00
版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
作者分享了个人博客框架迭代历程:从Hexo迁移到Astro的尝试,到发现Elog平台带来的启发,最终思考将Notion作为内容管理系统的新方案。文章重点描述了作者对博客系统的核心需求——解决创作同步问题,以及在探索NotionNext等解决方案过程中遇到的技术限制和思考。
使用VS Code的独立配置功能,可以为不同项目创建特定的配置文件,解决了在公司环境中因安全合规要求而无法使用第三方插件的问题。通过配置云同步和工作区单独配置,满足日常开发需求。推荐使用Codeium作为开源解决方案。
TypeScript 的类型声明文件 .d.ts 提供了 JavaScript 代码的附加元信息,支持类型提示和自动补全。使用 DefinitelyTyped 仓库可以为没有类型声明的 npm 包提供类型支持,类型定义可通过 type 和 interface 进行,declare 语法用于为已有的 JS 变量或函数添加类型。三斜杠指令用于引入额外的文件依赖。
前端模块化的演变包括CJS、AMD、CMD、UMD和ESM,现代浏览器支持ESM,webpack负责模块处理和打包,确保在浏览器中高效运行模块,支持代码拆分和Tree Shaking以优化性能。