怎么深入学习计算机,深入提高编程能力

笔者最近在学习计算机的过程中,好像遇到了瓶颈。

学了很多东西,但感觉都不是很精通,也不知道怎么深入下去,很焦虑很迷茫。

学了操作系统,学了计算机网络,学了数据结构与算法,深入学习了C语言,学了Python,学了C++等,但感觉学了和没学一样,心里特别没谱,也没做过啥项目。

因此这篇文章就是对这个情况的一个记录,以及我寻找的解决办法。


碰巧在知乎上有个和我现在情况很契合的问题:你的编程能力从什么时候开始突飞猛进?

下面我就以这个问题中的回答来审视自身,寻找深入的方向和方法。


回答1

阶段一:啥也不会,抄代码都运行不起来,学会了百度+google,学会了舔着逼脸去求大神。

阶段二:学会天坛看教学视频,得瑟能写一些页面,停留在CURD阶段,顶多培训毕业水平,疑难杂症无能为力。

阶段三:开始了解底层,看书研究底层,原来发现全是数据结构算法、操作系统、网络底层,开始沉迷研究底层技术,用优雅的设计。

阶段四:知道一些底层,开始跟别人喷技术的优雅性,忽略了我们技术是为了业务带来收益。

阶段五:能灵活判断业务的情况,给出合理的技术架构。

总之,突飞猛进的时候是自己会实践用起来,同时在项目环境中碰到问题,研究底层最终解决疑难杂症,随着经历无数个疑难杂症的积累,也就是这时候。

作者:码农皮邱
链接:https://www.zhihu.com/question/356351510/answer/1227322862


回答2

作者:胡嵩
链接:https://www.zhihu.com/question/356351510/answer/988891356

回顾一下,我的技术能力(不仅仅是编程,而是解决问题的能力)的进步大约有几个重要的节点:

  1. 刚入行时的入门练习题

这个是当年狼厂网页搜索部门的传统,不知道现在还有没有,入职第一个任务是完成两道练习题。一题是在Linux上用纯C(不许用C++,没有stl可用)完成一个多线程的网页抓取器,另一题是同样的环境语言完成2G大小的query(搜索查询词)的top100提取,有时间要求。

入厂之前我在Linux上没有写过代码。

两天时间从Linux基本命令的熟悉,vim gcc gdb的使用学习,从malloc和free开始搞内存管理,从0开始码hashtable(还得自己写hash函数),从socket开始实现http client和各种协议码解析,使用pthread多线程和信号量互斥同步,基本把操作系统计算机网络复习了一遍。

这两天把我四年本科三年研究生没搞扎实的工程基础全部补上了。

结论:有目的的练习,尤其是一个完整的应用问题的解决,是学习的不二法门。

  1. 接手一个完整的模块(子系统)

搞完入门练习,leader过来跟我说:小胡,现在有一个重要的模块交给你,赶紧熟悉一下,然后完成如下功能升级。

这个模块是前厂存储网页的核心模块,在当年内存4g的奔腾主机上单机存储几千万网页,几台机器存下了当时整个中文互联网。支持高性能的随机存取和顺序读,可以说把机器性能压榨到了极致。

3w行,纯C。

啃了几天终于搞明白了结构,(多年以后我还得感谢source insight),同时也对写这个模块的大牛佩服的五体投地,为了压榨内存把每一个bit都物尽其用,各子模块之间的分工又是那么的优雅。

然后是上手改,看懂了之后功能升级很简单,只改了十几行代码,但上线的时候真是手发抖!

后来才知道这个模块好几个前任都没成功接下来就被fire了…

后来又经历了若干次升级,解决各种诡异bug(搞过高并发存储系统的应该知道坑有多深),编码和解决问题的能力突飞猛进。

结论: 学习系统设计的最佳途径是看一个优秀设计的源码,检验成果的方式是改造它应用于你的实际场景。

  1. 接手一个完整的系统

搞定存储模块之后,我的下一个任务是升级喝扩展一个完整的抓取系统。

和入门练习做的抓取器不同,这个完整的抓取系统(又称spider)是工业级的,需要每天完成千万级的抓取量,还需要考虑并发压力控制,网页更新调度,垃圾网页处理,去重等等诸多现实的工程问题。

大大小小十来个模块,十来万行代码,大部分是C,还有接近一万行的bash脚本(用bash实现分布式的网页去重处理你信?)

这时会发现很多模块内部都有不少实现不尽如人意的地方,但是由于借口定义的好,模块直接容错性强,整个系统还是work的。

这促使我思考系统级的架构,最需要关注的重点是什么,良好的结构远胜于细节的雕琢。

大约小半年后,我对这个系统基本做到出任何问题能立刻反映到是那个模块出的问题,对问题的分析定位能力又上了一个台阶。

结论: 理解了接口定义和系统结构重于实现细节,就迈出了架构师的第一步

  1. 设计一个完整的子系统

此时大概工作快两年了,原来的抓取系统有一个很大的问题,就是积累的网页数太多,更新资源分配不过来,导致系统中大量网页在互联网上已经404但仍然会进到线上被检索出来。我们称之为死链接问题

通过对死链的规律分析,我发现互联网上大部分死链存在站点或目录级聚集的现象,这个其实很好理解,一个网站无力维护了,自然就全部挂掉,目录级很可能是网站改版了,或者一个子频道关闭了。利用这个规律,我们可以大幅度降低死链检测的资源耗费。

在这个认识的基础上,我设计了一个独立的死链检测系统。上线效果很不错,检查死链的流量开销降低到原来10%,网页库中死链还下降了。

结论: 架构师首选要解决的是待解决问题的精确描述,和对问题域的分布规律的挖掘,然后才是结构设计。

  1. 设计一个新的系统

工作第四,五年间,hadoop在业界逐渐流行起来,基于Google三件套的设计,当年的hadoop最上层的table还很不完善,但是mapreduce和hdfs已经很可以用了。 如何利用分布式基础框架改造系统,让系统更健壮(以及永更廉价的硬件給公司省钱),成了当时的一个重要问题。

整个抓取系统和建库系统的分布式改造,相当于重新设计一个新的大系统。需要考虑方方面面,如何逐步升级兼容原有系统?如何保证功能的完整性?原有设计中有一些不合理的地方,如何利用这次迁移同步改造?

主导完这些工作后,系统架构方面再也没有遇到搞不定的问题。

结论: 好的架构师需要在合适的时机解决重要的问题,业务发展才能给你这样的机会。

上面5个节点,大致是T3 T4 T5 T6 T8的水平。

新冠在家隔离,半夜睡不着码字这么多。看完给个赞呗。


回答3

口天师兄

百度多了你就明白:它也许有用,但它封印了你精进计算机英语的机会。

Google多了你就明白:各地大佬们的文章很Nice,但它们仅是你技术知识体系的精华补充。

开始读书了你就明白:你以往东拼西凑几十篇烂文才明白的事,书上那几页纸都写着,而且详细的很。

接触到国内外大社的经典书后你就明白:那些烂大街的21天宝典,7周速成,都是些什么玩意,误人子弟!图灵牛逼,动物牛逼,Manning牛逼。

好书读多了你就明白:技术是一环扣一环的,有牢固的技术知识体系,学啥都事半功倍。

多做业务你就明白:所学的技术该用在哪。

多做用户量大的业务你就明白:光会用技术,和用好技术是两码子事。

多找第三方开源你就明白:原来工作摸鱼不是梦。

太随便用第三方你就明白:某天需求一变,它兼顾不到,可以把你往死里坑,坑到你得去看源码。

第一次看完源码你就明白:开始还是很讨厌的,等全盘搞明白了,发现“咦~有点意思”。

源码看多了你就明白:自己的查克拉莫名的增多了。而且吐槽文档不全的习惯也渐渐少了,一个不服就跑去观摩别人的源码,顺便偷个师。再往后,或许你的技术确实突飞猛进了,然而你却只会觉得编程本来就是这个样子的。

因为,但凡通过点滴付出,累积出来的结果,都是平淡无声的。


回答4

作者:Cat Chen
链接:https://www.zhihu.com/question/356351510/answer/933373270

第一个阶段,是通过高强度的刷题来让自己的解题和编码能力变得够用,不会再拖后腿。这其实花了很多年的时间,因为我从小学开始就参加编程竞赛。最集中刷题的是高中,因为我害怕要去高考,所以无论如何都要 NOIP 拿个省一等奖换个保送资格啊。之后我没有搞 ACM,但我觉得也够用了。绝大多数编程问题,我都能想到用什么算法解决,然后写出来的代码不会有问题,就算有问题我也知道如何迅速调试。

第二个阶段,是学会阅读大量英文文档,然后学会使用合适的关键字进行搜索。老实说一句,今时今日几乎所有你想写的代码都有人写过类似的,你几乎不可能写出什么完全原创的东西来。可能你找到一个原创的方式把东西组合到一起来,但被组合的每一个部件都不是原创了。所以遇到什么具体问题,上网搜索一下就是了,常见的问题 Stack Overflow 上都有人问过,你绝对不是第一个问的。不常见的问题也很可能有人解决过,就看你是否知道如何用正确的方法进行代码搜索了。

举个具体的例子,现在跟前端相关的东西基本上我就在 MDN 上找,只有非常少数前沿标准是 MDN 尚未记载需要自己看 spec 原文的,真的需要的话就看 spec 原文咯。

至于使用各种开源框架和库遇到的问题,基本上早就有人在 GitHub 上提过 issue,可以看看那个 issue 是被如何解决的。很多特殊的用例官方都不可能直接修改框架和库来支持,但会商讨一个 workaround 让真的需要这样用的人绕过去。例如在使用 React hooks 时如果你真的有一个变量需要在多个异步回调中同步的怎么办?用 useRef 创建一个 ref,这个 ref 跟实例成员一样永远指向一个对象,然后 ref.current 就能用来存储共享的变量。这是官方 issue 讨论的结果。

如果你在 Facebook 和 Google 这样的大公司里,有完善的内部代码搜索,你会发现真的是你想得到的代码都有人写过类似的。有可能是之前某位大神写过了,有可能跟 blame 记录当年写那段代码那个 IC 现在已经是你的 VP。没有什么问题是全新的问题,更需要思考的是:你已经知道一个老问题和拥有解决这个老问题的代码,这对于你手上的新问题和现在新的上下文来说意味着什么?

举一个很实在的例子吧,前端要做一个 scrollable area,支持各种复杂功能,例如滚动加速减速要符合直觉,可以滚动后 snap to item,垂直滚动要允许 pull to refresh,容器大小要 responsive。其实这些代码都有人写过了,但你看公司内别人的实现你会发现他们写第一个版本时还需要兼容 IE8,后来才打上了各种补丁支持到 iOS 6,之后就没人碰过这代码。现在你要做一个新的,你还要支持 IE8 吗?你不是应该原生支持 iOS 13 然后再往下兼容吗?

对于编程来说,除非你真的走在最前沿,时至今日基本上你想要解决的问题都已经被解决过了,只是你有没有很好的英语阅读能力和老代码调试能力去把知识整理出来。相对于写代码解决问题的能力,更重要的是选择正确的问题来解决,兼容什么 IE8 就是个能解决但不值得解决的问题。


回答5

作者:牛岱
链接:https://www.zhihu.com/question/356351510/answer/1155780521

按照时间线走:

开始用谷歌,熟悉英文编程/学习环境。

原来高质量的免费学习资源如此之多,熟悉了英文环境减少了很多不必要的障碍,不再排斥英文的东西。

开始用 Github

了解什么是开源,开始被一些项目所吸引,学了怎么用 git,虽然不是很懂,但是在努力地融入这个社区,虽然可能都看不懂大家都在干嘛,但知道这个世界很丰富,很有趣。

自己写点小东西。

学了点语言基础写点小东西,不管时间复杂度,空间复杂度,不遵循代码规范,不懂设计模式,不懂数据结构,只求能跑起来,只求能“看起来”不错,虽然写的东西别人看不上,但看着小东西逐渐有了点样子,成就感满满,不求别人看得起,只求自己满意。

学习理论知识

写的小东西差不多了,心里有了很多疑问,开始学 数据结构算法,发现原来之前写的那个小东西有些做法十分低效,数据的表达方式也极其乱来,明白了什么时候该用动态数组,什么时候该用链表,明白了那个叫 hashCode 的函数究竟是干嘛的,学习的过程中根据学到的东西,再翻回去修改那个小项目,让那个小项目跑的更快,再过了一段时间,觉得小项目已经不足以满足不断膨胀的视野和想法,小项目停止了维护,开始看一些别的。

读源码并不难

为了解决一些问题,我怀疑问题不是出在我写的代码中,而是出在我用的框架/库中,没有怎么读过项目源码的我以为别人写的源码都是很高深难懂,实际去读发现,好的代码往往都是 简洁,易懂,直达目的的,消除了对源码的畏惧,也同时发现了一些开源项目的 Bug,抓住这个机会,给项目提交 PR,并被 Merge,还被官推转推,在那一刻,第一次感觉到真正融入了 Github 社区,从一个旁观者变成了参与者,从使用者变成了贡献者。

学习核心专业课

开始学习操作系统,计算机网络,编译原理等专业课,原先的一些关于底层运行机制的疑惑不断解除,破碎的知识不断地被联系在一起,成为了一个更大的地图,恐龙书,老虎书,图灵书,看经典教材往往能事半功倍,分层治之才能构建复杂系统,理解本质才能方寸不乱, 书不可不读,代码不可不写,反复循环互相覆盖才是进步之道。

开始综合利用所学,开发更大的项目

随着知识体系变得更加完整,工具的使用变得更加熟练,可以把以前的一些有想法但没能力实现的东西实现了,比如,超过十个微信公众号转发的,发布这篇文章所用的插件:Zhihu On VSCode


回答6

作者:张彦飞
链接:https://www.zhihu.com/question/356351510/answer/1634583036

大家好,我是飞哥。我来分享一下我的编程技术成长方法,如果用一个词来概括,那就是:深度思考

当你工作了以后,你会发现你没有办法像在学校里那样有好多大块大块的时间来啃各种各样的经典书籍了。即使你啃了好几遍,过一段时间不用很可能你就又忘了。

当你工作了以后,你的大部分时间将被工作上的各种琐碎的会议、业务需求、线上维护、bug处理所占据。前辈们都建议你下班后晚上8点到10点不要娱乐,要充电学习。但是每天这个时候的你可能还在公司没有下班。

当你工作了以后,可能感觉每天做的都是各种杂事。不单单技术感觉难以成长,就连年底的绩效考评成绩可能也是平平淡淡,没有亮点可言。你的自信也在一点一点的被磨没。

这种情况下,怎么破局,来保证自己的技术能力能够持续进步,工作绩效能够突出?

办法总比困难多,我来分享下我在工作中的技术成长方法,供大家参考。我个人从10年硕士毕业以后到现在已经工作了10年多了,在腾讯、搜狗等大厂混迹了9年之多,现在是搜狗的专家开发工程师。我分享的方法可以分成四步

我们逐条展开来分享:

1. 保持好奇,勤于在项目中发现问题

我在日常code之余会有节奏有目的地推进自己的理论思考。没错,我用的字眼不是学习,而是思考。我对工作中看似司空见惯的问题发起疑问。

2011年我在腾讯时,那时候还是一个新人。当时老大给我分配到了一个模块,所有合作方数据源的图片下载模块。这个模块的需求描述起来也很简单,就是把合作方数据中的图片url摘出来,然后下载并存储到腾讯的服务器上。

这个工作从开始到完成不需要太长的时间。但是在这个过程中,引发了我很多的思考。比如新建一个空文件的话消耗磁盘空间吗?一个文件夹下最多能存多少个文件?文件名太长了的话会影响系统性能吗?Linux在学校的时候大家也都学过,但是对于以上这些问题我却不能给自己一个很好的答案。

基于这些疑问,我自己翻了不少资料,做了不少的实际测试,然后写出了《Linux文件系统十问》。该文章在腾讯内部KM上成为了年度热文,当时有几乎1/3的同事都浏览过(腾讯有很多非技术员工,所以1/3的阅读覆盖率很高了)。现在这篇文章不好找了,想看的同学可以看下面的新文章地址。

再比如有一次我们自己维护了一个线上的redis(当时工程部还没有redis平台,redis服务要业务自己维护)。为了优化性能,我把后端的请求由短连接改成了长连接。虽然看效果性能确实是优化了,但是我的思考并没有停止。我们所有的后端机都会连接这个redis。这样在这个redis实例上可能得有6000多条并发连接存在。我就开始疑惑,Linux最多能有多少个TCP连接呢,我这6000条长连接会不会把这个服务器玩坏?

我的这篇文章

《漫画 | 一台Linux服务器最多能支撑多少个TCP连接?》mp.weixin.qq.com

就是这么来的。这个深度的理解对我后续的工作有极大帮助~~

还有我一直好奇网络包是怎么样从网卡上到达我们的应用进程中的。啃了好久的Linux内核,又整理出了

《图解Linux网络包接收过程》mp.weixin.qq.com

2.带着问题去深度思考、查各种资料

在我思考的过程中,我需要回头去翻各种经典书籍、看Linux的内核源代码,以及其它各种网上的资料。曾经有一次为了把一个内存的工作原理的问题弄明白,我嫌家里的书少,网上的资料不够,直接跑到国家图书馆待了半天。

我这里把能收集到的电子版本,都整理好了,谁需要可以通过以下地址下载。

下载地址: https://pan.baidu.com/s/1yzSbhD96wdfYW6ncA9cN7A

提取码: 4uqa

虽然Linux是开源的,但是还是有很多同学不知道去哪里下载源码。我这里也贴一下

Index of /pub/linux/kernel/mirrors.edge.kernel.org

3. 别偷懒,加上动手验证实测

在看完书,查完各种资料后,理论上你可能得到初步解释了。但其实这个时候你的理解深度还远远不够。而且还有可能是你查到的资料是片面的,甚至有可能都是错的。

这时候的动手实际测试显得尤为重要,用各种性能测试工具也可以,自己直接亲手写一段代码也ok。反正就要用实践检验理论是否正确。不正确的时候,再去别的地方搜其它的解释。如此往复迭代,直到把疑惑彻底消灭掉为止~

我在平时对各种结论都是要直接动态测的,以下文章都是我实际动手测出来的。这种动手测出来的数据你基本不可能忘了。你会印象非常深,它真正内化到你的思想中,你的技术栈上了。

《聊聊TCP连接耗时的那些事儿》mp.weixin.qq.comhttps://zhuanlan.zhihu.com/p/87827480zhuanlan.zhihu.com图标《揭穿内存厂家“谎言”,实测内存带宽真实表现》mp.weixin.qq.comhttps://zhuanlan.zhihu.com/p/152291597zhuanlan.zhihu.com图标

4. 将你的成果用起来,提升项目效果

最后这一步是点睛之笔。 只有对实际工作提升的技术才是有价值的技术。把你的深度思考的结论应用到项目中,将项目的效果进行提升

举个我几年前的小栗子,当时接手了前任开发留下来的一个推送模块,推送一次要跑将近12个小时。经过我剖析业务逻辑后发现主要耗时都花在了用几百万的imei到一个几千万条记录的数据库里查询了,大量的网络IO加随机磁盘IO。

我把业务逻辑进行了改造,也没有使用传统的sql优化方法。而是一次性将表中数据全查下来。然后在本地机器上在执行顺序读取遍历查询。这样大量的网络IO、大量的远程mysql server的随机磁盘IO全被我干掉了。在mysql上和本地服务器上全部都是磁盘顺序IO。整体耗时直接从12小时下降到了20分钟左右。

当你每次都能用你深厚的技术能力把工作效果提升好几倍,你的绩效想不提升都很难。这个时候的你其实就达成了一种技术和工作互相促进的良性循环


看了上面的回答,我结合自己的情况来规划自己后面的学习方向。

夯实基础

采用看书,看视频,看博客多种方法来学习计算机基础知识,包括操作系统,计算机网络,数据结构与算法等。采用多种方法的好处是可以提高学习效果,不容易枯燥,学习的内容相互补充。

每天一道LeetCode题,并且写成博客记录。

多写代码

要有意识的多写代码,这个时期可能还不是一些大的项目,而是一些类似图书馆管理系统这样的练习题,但是代码量小,容易写。在这个过程中,我们会学习到写代码的一些细节,提高代码能力。

这个时期,我们的练习题一般对我们的要求比较少,我们可以根据自己想要练习的知识点来增加这方面的功能,有意识的练习。

在这过程中,我们还可以思考,当需求变化时,我们的代码要怎样修改,我们的架构是否合适,不断的迭代,不断的有意思的学习。

多做项目

只有在实际的项目中,才能体会到复杂性和需求的变化性,项目一般代码量大,业务逻辑复杂。要想完全看懂源代码都是很难的,因此我们在看源代码的过程中,我们需要一般理解,一边改动代码验证和加深我们的理解。后面也可以修改某个模块的内容或者增加某个模块的内容等。这边关键是要搭建验证环境。

具体到做的事情就是

习惯英文环境

有空余时间可以刷刷视频学习,看看博客。

大片时间的话可以看看书。

找一些小型的练习项目,不断改编。

找开源项目学习,了解怎么学习开源项目,怎么调用开源项目,怎么修改开源项目等,当然关键是搭建使用开源项目的环境。
写博客记录,在写的过程中也是一个加深理解的过程,我现在发现哪些你自己写过的内容,就会格外的熟悉。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小熊coder

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值