欢迎光临散文网 会员登陆 & 注册

杂谈 - 近两个月的编程学习与其他

2022-07-04 02:49 作者:ZeromaX訸  | 我要投稿


有一段时间没有用文字记录一下自己的学习及其他的思考了。前段时间(5 月到目前)主要杂七杂八学了不少东西,学习过程中总感觉自己初学不久掌握不深,就不太好意思把相关东西写下来。但两个月的时间下来,就发现因此辍笔就更加不想写了。还是需要不论如何都多多输出,才能在写作的过程中去梳理自己的思想和积累经验吧……

闲言少叙,进入正题:下面将相关的一些思考简单归类,然后每条线按时间线流水账式地聊聊自己最近的一些想法吧。

一、Java 17 -> Scala -> Haskell

之前在各路平台的文章里面看到这样一个事实:Spring 6、Spring Boot 3、Elasticsearch 8、Kafka 3 这些框架的最新版本的都不再支持 Java 8,而普遍需要最新的 LTS(长期支持)JDK 版本——Java 17。当时二月份也整理了一下 Java 从 8 开始直到 17 的新特性,但由于自己一贯的惰性,并没有真正安装 JDK 17 试一下。

然后借着学习 FXGL 的过程(后面会提到 FXGL,简单来说就是一个基于 JavaFX 的游戏引擎,最新版本需要较高版本的 Java),就把 Java 17 给装上了,实际使用了一下。说实话,感觉版本号增加了不少(现在其实最新的已经是 2022 年 3 月的  Java 18,只是不是长期支持版本),但因为 Java 现在是六个月一个版本,所以其实从 9 开始只是过了五年不到,其间的对于程序员可感的新特性其实并不多。其实想来印象深刻的也就是:模块系统var 类型推断switch 和 instanceof 表达式加强Record 类密封类一些 Stream 和 Optional 流的加强集合类库 API三引号文本块之类的修改,其余很多就是内存回收器方面的更新了。

当时学完 Java 17 的新特性,自己就想捡起原来学 Java 8 函数式编程时顺便简单学的 Scala 再研究研究。因为很明显的:单就 Scala 的 match 模式匹配这一点,历经好几个版本 switch 语法上的不痛不痒的优化,类似 Scala 的模式匹配守卫之类比较实际的强化 switch 功能在 Java 到 18 还处于第二次预览状态。类似元组这些功能则根本还没有。那我为什么不试试再深入学习一下 Scala,了解一下它更多的特性和函数式用法呢?

Scala

于是说干就干,直接搞到一本 Scala 语言缔造者 Martin Odersky 的《Scala 编程(第四版)》,对着书边敲边学。因为之前有过看《Scala 函数式编程》学习的经历,所以上手还是比较快的,差不多一周时间就把主要部分都基本看完了。学习完一些深入的特性之后,就更加感觉 Scala 的简洁和设计上的巧妙,只是自己功力还不够,很多深入的特性——特质混入、提取器、函数式编程的一些高级概念之类的——还不是很熟悉。但简单上手拿 Scala 刷了一段时间力扣题目,感觉确实比 Java 简洁不少。

至此就不得不感叹只学一门 Java 也许确实会限制自己的眼界。不提其他语言的话,单是 Java 就很容易受困于一个现实:业界因为生产环境求稳或者 Oracle JDK 的商用许可证问题,而普遍使用的 Java 8(网上看甚至有的老项目还用的是更老的版本……)。那么新的特性就很难在工作环境接触到,如果自己没有探索的精神,那视野就很可能限制在此了。更不用说很多人在提到新特性的时候就是有种不愿意了解、不愿意学习的心态,甚至 Java 8 的 Stream 都谈之色变,一提起就是以可读性差、速度慢、容易出 bug 之类的说法拒绝,但其实有时候原因却只是不肯面对认知范围以外的新事物,在对新技术还不甚了了的时候就先做出了先入为主的判断。不知道我自己将来会不会变成这样?不过个人感觉大概率不会——就算日后学不动了,起码我可以做到不对自己不了解的东西妄断结论或者人云亦云。

之后可能进一步去学习一下 Scala 吧,有什么心得也顺便分享一下。然后在学习 Scala 函数式编程时,就看到很多人提 Haskell,因为自己到现在也不太熟悉函数式编程的写法,加上也比较好奇纯函数式编程是什么样的,就把 Haskell 的开发环境搭了一下,按照《Haskell 函数式编程入门(第二版)》按部就班地学习。目前还在学习过程中,之后有什么感想再分享一下吧。

Haskell

不过搭 Haskell 环境的过程倒是让我感觉有种回到过去刚开始学习编程的感觉——以前是自己啥都不懂,折腾环境安装就是两眼一抹黑按照网络上的教程一步一步来,其实自己做了什么都不理解。虽然现在编程经验有了,但 Haskell 需要面对的问题其实也不少。因为自己选择的环境和书上直接使用 REPL 不同,想要建一个 Git 仓库一边学一边记,不想再和以前学习过后什么都不留下来的情况一样(这样日后不方便复习或者查看);所以 IDE 采用的是 IntelliJ IDEA + IntelliJ-Haskell 插件的组合,因为插件的原因,所以也就是基于 Stack 安装的 Haskell 环境。这一系列的安装过程,因为中文互联网上资料较少或者过时了,就只能自己慢慢趟坑了。

安装好了环境以后,写代码其实也很像以前刚学 C 语言时候。当时硬是要求我们 Visual Studio、(甚至老旧些的) VC、 Dev-C++ 这些 IDE 都不要用,让我们这些初学者直接用 Turbo  C (这个名字我回忆不起来还搜了半天才找到)这种 DOS 时代的编辑器来学……所以硬是把编程上手门槛抬高了。Haskell 则是因为本身不算大众,所以相应 IDE 发展不算特别充分,让我这个被 IntelliJ 全家桶惯坏的 Java 开发感觉有点再回到从前。不过后来发现 Stack 上面安装不少包后配合插件,还是可以补充不少功能,只是都需要自己折腾罢了。有空也整理一下自己的经验分享一下(挖坑),目前其实也可以直接看我 GitHub 上面的 HaskellProject README,简单写了一下自己的过程,只是没有整理成文章。

以上就是自己近段时间语言学习相关的内容啦,其余还有些 C# 相关的内容后续再提。有些人说,程序员有必要每年学一门新语言。这话可能有点绝对,但道理我感觉确实如此。有对比才有思考,不然就容易固步自封。这里说的新语言,还一定得是在思路、设计上有独到之处的地方,自己也必须学习到深度才行。不然其实很多语言的基础语法其实都是大差不差的,而它们各自独特于其他语言的优势才有启发性。

二、Guava -> JUnit -> Mockito -> 日志框架

五月份的时候其实也算是沉下心来整理了不少细节东西,主要就是工作中会用到(或者没有用到,但我感觉有意义)的一些边边角角的知识,之前一直没有系统化地去学习一下。具体来说就是围绕着软件工程实践过程中的一些工具库、单元测试、日志相关的学习。

先是捡起了之前学了一半的汪文君的 Guava 教程啃完了。其实目前也只是作为自己一个知识储备,实践的话,不得不说不算深入。单论工具库,很多人都说没必要深究,只用些简单的功能,用到的时候看看就可以了。暂不论这些观点到底正确与否,不过我学习的目的主要还是感觉自己缺少这方面对类库的“审美能力”——如何区分一个库的设计的好坏;以及更进一步的——如何自己去设计一个使用方便、可读性优秀、设计良好的库的“落地能力”。而对于这些能力的学习,我个人经验只是靠自己思考或者读书、看教程视频之类的方法是很难的。一方面是这些资料确实也相对较少,另一方面就是这些经验也许又必须通过源码阅读看得多了才有感觉。自己目前只是暂且在这块留下一个相对深入的足迹吧,日后如果想进一步学习,也就有了一个对比的标杆。

JUnit 5

然后就是把汪文君的 JUnit、Mockito 教程也学习了一下。自己之前一直有在想项目重构过程中的问题:工作中体系化的单元测试基本就是没有,导致就是开发过程中很多问题;而没有单元测试这个事实又和整个架构形成一个循环,导致代码没有按照可测试的方向发展,螺旋向下增加后续想添加单元测试的难度。学习的目的就是希望能经过这些学习,慢慢加强自己对这个领域的思考。有机会的话,可以在自己个人的项目里面进行实践。不过因为自己没有真正经历过完善的单元测试下开发的过程,很多东西也还是在个人学习、摸索的过程中,不得不承认会有很大的限制性;如果没有这样的工作机会的话,日后有机会还是得写写大点的个人项目,然后把这些学习融入进去,才能体会到这些规范对于开发过程的帮助吧。编程嘛,实践才是最重要的,只是目前的自己还是很难找到一个让自己长期投入进去的项目。

而学习日志框架也是出于工作中遇到的各种找日志难、爆磁盘等问题后,想系统地学习一下日志框架本身提供哪些功能供开发者使用。自己以前对于日志框架的认识确实很浅薄,不得不说,就算不学太深,明白框架本身的能力范围也很有意义。知道框架能做什么,才能够在遇到相应问题时想到,然后深入去学习。

总体来说,这部分学习主要的目的还是给自己在工程实践过程中的查缺补漏吧,感觉自己这方面能力还是相对较弱,还是得多在写代码实际的磨练中成长。

三、JavaFX -> FXGL -> LibGDX -> Unity 和 C#

接下来就是一些自娱自乐的学习了——关于游戏开发的学习。

其实因为自己玩游戏比较多,现在也逐渐走到了一个俗话叫做“电子 ED”的阶段,很难对自己感觉没有新意的游戏打起兴趣,就一直想能不能自己在业余时间可以把一些有意思的想法落地实践一下。那么要落地的话,就得学习一些游戏开发的技术了。

以前有尝试过直接上手 Unity,感觉主流的教程和自己的目标不太一致——一般网上的教程都是带你把常用的工具功能跑一遍,常用 API 使用过一遍。这样跟教程操作下来,大部分的内容都很散(游戏本身就涉及多个方面——代码、建模、动画),自己脑海空空,留下了印象但是还是很难自己从零开始,真正写一个自己的游戏。我自己的想法其实还真不是去游戏行业就业什么的,就是想自己写点代码,在游戏机制上做点创新的尝试罢了。其实我理想中最简单的形式,那就是类似放置类游戏(Idle Game)那种,只需要实现基本游戏本身的游玩逻辑即可。

这个时候自己就感觉到自己缺少的,可能还是和客户端(不管是移动端还是网页端)相关的开发经验。因为缺少这些,在界面开发过程中就很迷茫——如何与后端交互,如何实现界面效果等等——完全一无所知。所以自己就想了一下大致的学习方向应该如何:虽然安卓、iOS 之类的没学过,但之前也试过学习前端的知识来实现(甚至用 js 写过一个网页扫雷),同样感觉大量知识糊脸的感觉很容易让自己迷糊。于是就大致在 Java 体系内寻找解决方案,因为之前也接触过一些 Swing 的开发(用《Java 核心编程》上教的 API,拼凑了一个五子棋的游戏),所以就想能不能用更加新近的 JavaFX 来开发练练手。

Java FX

于是之前就在哔哩哔哩上找了 aimls 的那套超长的 JavaFX 教程(200 多集)啃,啃到七八十集的时候(学完绑定再加几集)就没学下去了。今年五月份就是从这里重新捡起来看,老老实实把 200 集以内的内容学完了。后面一些音效相关的感觉和我自己目的距离较远,就暂且没看,以后有用到再具体看。不得不说,这样一番折腾下来,倒是确实让自己心态平静不少。之前多多少少有些急功近利的思想,总想着短时间内“整个大的”;但真正踏踏实实每天花些时间跟着敲完代码,最后真正学完的感觉,真的让我体会到了“千里之行始于足下”的感觉。

不得不提,其实五月到今天以上所有其他的学习,都是在这个学习 JavaFX 经历之后的。正是这之后我才更愿意多写写代码。之前很多时候是宁愿读编程相关的书、敲读书笔记或者看视频学习,也不愿意按书上、视频里的内容写代码(虽然有过,但是相对来说更不情愿)。

学习了 JavaFX,就从它 API 的使用过程中,体会到了 GUI 系统的一些基本的设计要点。接着就是想要学习游戏引擎相关的内容了,我就在 Java 体系中找到了 LibGDX 和 FXGL。LibGDX 是 Java 游戏引擎中比较知名的一个了,Steam 上大火的卡牌 rougelike 游戏《Slay the Spire》(杀戮尖塔)就是使用的该引擎。而 FXGL 则是基于 JavaFX 的游戏引擎(正因为它我的 JDK 升到了 Java 17)。

最一开始是考虑从 LibGDX 入手的,因为相对来说更成熟,有完善的文档和开源商业级案例,以及许多配套的开发工具。但是因为六月初网络的原因,libGDX 的那个项目初始化工具一直下不下来,就先用 FXGL 学习了(直接 Maven 导入依赖还是方便)。后来正常下载了 libGDX 的项目初始化用的 jar 后,就也开始学习 libGDX 相关的内容。目前还在学习过程中,中文互联网上感觉也是相关教程比较少。相比成熟的 LibGDX,FXGL 反而在 B 站有 LeeWyatt 个人出的一套教程。

最终工程实践上,那肯定还是 Unity、Unreal 这些引擎社区规模最大了。因为自己之前简单学过一点 Unity,所以目前也在一边学些 C#,为之后进一步学习做准备。学习 C# 的过程,又是进一步感觉 Java 语言本身特性发展缓慢…… 不过毕竟语言的使用规模和整个技术栈、社区的发展都密切相关,所以倒也很好解释为什么今天的中文互联网上,C# 教程大部分都和 Unity 挂钩……

四、关于八股文和工作实践

流水账写了这么多,基本聊完了这段时间技术方面的学习,谈谈这段时间的一些想法吧。

在五月份之前,其实自己在做的事情主要就是整理这些年来学习的面试八股文相关的知识。前面也提到自己以前更倾向于读书、看视频学习,所以也不得不说,看了不少和编程相关的书籍。但是“读万卷书,行万里路(写万行码)”却没做到,看了一堆八股文的知识,却填补不了我内心里的很多迷惑。

孔子有云:“学而不思则罔,思而不学则殆”。自己之前的经历正是看了许多偏向面试相关的内容(虚拟机、各种数据库底层实现),而这些又不太方便在实践过程中加深印象,就因为看得多写得少忽略了很多细节。所以就得一遍一遍去读,从此给自己留下一个和自己认知范围断层的空中楼阁,然而这些知识和自己的实践过程却显然存在一个落地的断层。不得不说,自己如今愈发感觉这般下去危害无穷。所以前文也提到,感觉未来终究还是需要自己从零开始打磨一个个人项目出来。

这问题一方面是刚才说的思学结合的问题,还一方面就是感觉到在这样的过程中,自己的视野也就被互联网主流内容限制住了。当前编程相关的资料,大部分都是面向初学者(比如培训班教学或者面试题),要想专研深入一点,那就得看书。而对于很多新兴的或者相对不热门的技术,中文书籍又是相当稀缺甚至没有的。所以总得让自己沉下心,去阅读英文文档或者书籍,然后亲自实践出真知,这样才可能打破这层逻辑给自己打造的信息茧房。

前几天刚好在工作过程中也碰到了 Redis 大 key 的删除操作超时的问题,之前正好在面试题整理时也写过相关的,但只是看书和博客,没有太深入的体会。线上排查这些问题才更加切身感受到这些设计的目的,就更加感觉到以面试为目的学习这些知识未免过于功利,还是需要多结合实际代码过程,去慢慢把知识内化成自己的认知体系一部分。

编程学习也是需要“但行好事,莫问前程”的心态啊~

五、游戏以及游戏相关

文章进入尾声了,也聊聊最近这周末的个人的一些思考和实践吧。

前面学习的过程中,倒是也一边打了不少游戏。之前基本就是每日打打《战争雷霆》《原神》,其实快到游戏末期,发现走到游戏性被数值消磨掉的时候,基本就是我退坑的时候了。

《战争雷霆》是打到空战 IV 发现飞机最少也需要 40000 多研发,而我没氪金币机和高级账户玩街机空战上加成卡也就最多几千(不想玩得太累,就没去打历史模式),这样算也要打十几局才能解锁新飞机,实际只会更久。更不要说买飞机和改装需要的银狮币,要形成战斗力起码就得几十局了。顿时感觉自己没那么多时间耗在这上面,然而如果让我自己氪金,又感觉氪金也是爬科技线很慢的样子,性价比不高……所以最近也玩的少了,也就每天签个到,偶尔兴致来了就打一局守卫或者街机。游戏倒是还留在电脑上,也没卸载。

战争雷霆

《原神》则主要是游戏内容基本被我消耗光了,剩下就是我认为无意义的肝极品圣遗物刷深渊的过程,所以直接卸载了。当初原神刚出后一段时间的时候其实试了下,但毕竟也玩过《塞尔达荒野之息》,蒙德早期的体验相比之下还是差点意思,就没玩下去。春节时候看几个表弟在玩,就发现几个新地图的机制还是有点意思,春节过后刚好有段时间没啥想玩的游戏,就又下回来试了一下,雪山那边的探索感觉游戏设计上确实有进步,就玩下去了。然后就玩到现在,主线任务,支线任务,角色任务都做了许多(当然,不可能是 100 % 的),角色的一队(雷国)二队(凌华+夜兰+罗莎+砂糖永冻)也基本成型,就感觉可玩的东西基本都差不多接触过了,再用漫长的时间去每天用完体力换经验摩拉和圣遗物,以及清空每日委托,在我看来已经没有太大的意义了,不过是类似“1 级的时候用【破损的木棍】打【小龙虾】,100 级的时候用【传说级(你想加的各种定语)奔雷法杖】打【史诗霸王无敌巨钳虾】”之类的把戏罢了。于是为了避免浪费时间,这周末就卸载了。

现在玩游戏的心态也确实和以前不一样了,总是考虑不能太花时间。之所以《原神》《战争雷霆》这两个游戏最近玩的比较多,也正是因为《原神》是 PC、手机双端游戏所以可以利用一下通勤时间,而《战争雷霆》守卫模式和街机模式一局就二十分钟不到。而耗时间的游戏倒也不是不玩,只是需要对于我来说足够新颖或者说有意义。结果有趣而又让我深思的就是——这些我以不花时间为目的玩的游戏,反而吃掉了最多的时间。

现在来回想,《战争雷霆》可能是因为对我而言属于拟真和娱乐性结合比较好的载具战争模拟游戏,相对有价值一些(虽然玩到被数值卡脖子的感觉还是很不爽);那《原神》游玩过程中的时间到底有多少算是真正给我带来比较新奇的体验呢?可能是一些地图上的任务,或者地图设计本身的机制,抑或是不同角色技能的新鲜感,但不得不承认,大部分的时间还是消磨在了每日任务、体力换资源的过程中。重复地去打区域 BOSS、地脉之花、特定怪物去收集升级所需的材料,才是主要的时间去向。

这也许就是我暂时退坑的原因吧,未来也许有时间会下回来看看,但估计也是像自己玩《Warframe》那样,到了内容耗尽之时也就到了隔多个版本才看看的阶段。这也许就是数值驱动 RPG 的游戏在我这里共同的结局吧。

不过话又说回来,在对这种游戏的吸引力分析的过程中倒是也给我不少启发。网络游戏很倾向于使用的手段,就是需要合理利用每日任务之类的手段使沉浸到游戏有趣部分而开始关注最大化游戏收益的你愿意在其中消耗时间与精力。那么,吃了游戏策划喂的那么多的 * ,我们能不能找到一个类似的手段,让自己去吃学习过程的艰难困苦呢?我想应该也是可以的,之所以我现在又重新开始写点文章发一发,一部分也是出于这个目的。可能不能坚持太久,其实也无所谓,写下来的东西就是收获,就像游戏里面涨的经验一样,只是现实世界你得自己绑定一个你想要的目标,设计属于自己的任务,让你的生活成为感兴趣的有意义的游戏。

我自己主动建立类似游戏的正反馈机制的过程其实就是之前 Git 上面尽量每天写点代码或者读书笔记,然后就是 LeetCode 上天然的每日一题。也不要求自己真的就必须每天去做,重要是要建立自己一个小而频繁的习惯。当你习惯了小量时,就可以慢慢加量了。目前来说,Git 仓库坚持相对较好,LeetCode 马马虎虎也刷了近 800 多道题了。这个过程必然会有失败,注意力稍微变换目标,可能之前你想做的事情就中断了,但这次的失败未尝不是下一次的尝试的经验呢?其实用来打卡的 Git 仓库我就建了 3 个了,最近这个才培养了我写代码的习惯。

所以希望自己能够把最近这股劲头持续下去吧。本文也是临时起意,本着简单上手先做起来的想法写的,结构或者行文多少凌乱,能看到这里的话,也是辛苦了~ 籍此整理一下最近的思绪,如果能对读者有所帮助就再好不过啦~


杂谈 - 近两个月的编程学习与其他的评论 (共 条)

分享到微博请遵守国家法律