当前位置:   article > 正文

你的编程能力从什么时候开始突飞猛进?_warp_idx

warp_idx

在啃掉一本本计算机经典书籍和写下大量代码以后。

疫情原因回不去学校,作为一个马上毕业,即将入职腾讯的大四生,分享一下自己的学习历程吧。

本人在大学之前从未接触过编程,最开始的编程学习还是在高考完后,从书店买了本C Primer Plus,然后暑假开始啃,前前后后也就看了几十页。

大一上的时候,来到了华中师范大学,还没有转专业到计算机,一直在自学C语言和看一些计算机入门书籍(编码、计算机科学概论)。当时也很迷茫,不知道以后道路如何,所以也学了一些杂七杂八的东西(前端 python啥的),所幸的是,当时坚持把C Primer Plus结结实实地精读了一遍,而且几乎练习题都做了,算是比较好的开端。

大一下,转专业到计算机了,开始自学数据结构,算法和C++,部分看完了 数据结构与算法分析,并且把书上的数据结构实现了一遍,记得当时五月份给自己的flag是看完C++ Primer,然后每天上课看,晚饭吃完后也跑去七号楼刷书,最后囫囵吞枣似的看完了大部分。

大一暑假,txr大佬

@杏仁糖

给我说他面试通过了华科的联创团队Unique Studio,而且给我说他们团队都特别厉害,有些人在军训的时候就把C++ Primer给蹲着看完了,当时十分钦佩,幻想也能够进入贵团队。于是打算在大二上的时候,去报名他们的秋招。所以,那个暑假在学校自学,呆了五十多天。最初,拿起一本APUE,看了一章后感觉看不懂又放下了。然后,又拿起一本红色封面的算法第四版,这本书看完了,并且用C++把上面的算法都实现了一遍。另外,听知乎大佬说CSAPP是必看的神书,当时也懵懵懂懂地看了前面三章,做了lab。为了学习linux,还看了一本叫linux命令行大全的书。武汉的夏天很热,只能寂寞待在宿舍的我,打开了LeetCode的世界,写了一百多道题。

大二上,十月,忐忑迎来了联创的面试,前面两轮都过了,直到其特色的“熬夜测试”环节,因为实力不足+精力不足,测试败北,没有通过。清晨七点,在回学校的公交车上思考自己不足,总结是知识体系仍然不够完全,而且深度也不够。后来这个学期有点“误入歧途”的意思,入了Machine Learning的坑,记得当时花了好几个月刷完西瓜书和吴恩达机器学习课程的讲义(真佩服当时的毅力,都是英文和公式推导),后来想了想,ML/DL这个东西有点玄学,于是毅然决定成为一名做工程的程序员。总的来说,虽然这个学期的时间都投入到ML的学习中,没有学习工程方面的东西,只有用python写了一点好玩的爬虫,但是给了我以后坚定走工程方向的决心吧。

大二下,这个学期是打下计算机知识基础的关键时期。从知乎找了一系列书单,看完了CSAPP(做了lab,为了bomb lab还通宵了,强迫症想让自己把炸弹都拆了)、半本算法导论、effective C++、计算机网络系统方法(前三章)、部分TCP/IP详解等,做了一些项目,比如正则引擎(这个是参考了轮子哥的教程)等等,尝试写JSON库(未遂)。其实,因为学校只是一个普通211,找到好工作的学长学姐先例很少,一直是没有信心自己能去大厂,直到当时了解到myk

@孟永康

学长在春招收割了一系列offer后,才有了些许信心,相信自己如果能够像他那样努力,那么也能够找到好工作(感谢myk学长那时的鼓励和指导)。所以,定下了一年把自己水平提升到能够在大三下春招的时候拿下大厂offer的目标。

大二暑假和大三上也一直为这个目标奋斗,补上了APUE、部分UNP、深度探索C++对象模型、STL源码剖析、操作系统概念、操作系统真象还原、Linux多线程服务端编程、部分C++ template、部分C++ Concurrency in Action等书籍。然后,也一直没有放弃刷题,LeetCode写到了三百多道。同时也做了一些项目,跟着操作系统真象还原写的操作系统、简单的协程库,阅读了一些优秀的开源项目,SGI STL、muduo、libgo、libco等。中途还对haskell产生过兴趣,打印了一本Learn Yourself Haskell For Great Good,看完后感觉坑太深,还是专注找工作吧,haskell对我一直都有很强的吸引力,但是这种也只能作为爱好吧。另外,编译器也是有这种魔力,看了部分编译原理(龙书)、部分现代编译原理(虎书)和部分Engineering a Compiler,多次尝试写自己的编译器,多次未遂(不过现在有空了,在补上之前的烂尾项目)。当年的笔记哈哈:

img部分学习笔记

时间到了12月份,9号楼某个自习室内,txr大佬一直鼓励我去投简历找实习,本来我一直畏畏缩缩,对自己不太有信心,被鼓励后想着投就投吧。当时投了字节跳动和momenta的实习,面试都比较顺利,于是在大三上就在字节跳动开始了愉快的实习,比自己的计划早了大半年。当时为了准备面试,看了好多牛客网的面经,查漏补缺式地补齐自己的知识盲区。

大三下,基本都是在实习,学习了很多工程实践上的东西,接触了go的技术栈,并且对devops软件工程方面有了认知,包括代码管理、发布流程、微服务啥的。然后实习的时候骑驴找马,找到了腾讯的暑期实习。因为这个时候没有了找工作的压力,所以开始学一些自己感兴趣的东西,包括Rust(至今水平还是不太行)、分布式系统(DDIA、MIT6.824等),零零散散学了点东西。

大三暑假,腾讯实习了两个月,开始学习kubernetes、各种中间件等实际业务用到的东西,这个时候就感觉拥有到扎实的计算机基础是最重要的东西。

最后,顺利拿到了腾讯转正和字节跳动的秋招offer,两家都给的比较高,选择了工作体验更喜欢的腾讯哈哈。

总的来说,学习计算机是需要积累的,花一两年时间啃下那些厚厚的经典书籍后,才能构建自己的知识体系,然后阅读大量优秀源码,做一些有趣的项目,编程能力就能突飞猛进啦。

现在回头来看,大学时光真是如此宝贵,这是人生中为数不多可以静心学习的一段时间,可以不用考虑任何其他事情,每天学习十多个小时。



百度多了

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

Google多了

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

开始读书了

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

接触到国内外大社的经典书后

你就明白:那些烂大街的21天宝典,7周速成,都是些什么玩意,误人子弟!

图灵牛逼,动物牛逼,Manning牛逼。

好书读多了

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

多做业务

你就明白:所学的技术该用在哪。

多做用户量大的业务

你就明白:光会用技术,和用好技术是两码子事。

多找第三方开源

你就明白:原来工作摸鱼不是梦。

太随便用第三方

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

第一次看完源码

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

源码看多了

你就明白:自己的查克拉莫名的增多了。而且吐槽文档不全的习惯也渐渐少了,一个不服就跑去观摩别人的源码,顺便偷个师。

再往后,或许你的技术确实突飞猛进了,然而你却只会觉得编程本来就是这个样子的。

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



每次信息流刷到这个问题,都会拨动我记忆的缓存,让我想起那段大起大落的时光。

自从写完那个项目后,我没再怕过任何代码。

19年夏的某一天,在各大公司陆续推出自己预训练的BERT,并开始用它们做离线任务时,lead把我叫进会议室,说老大想上线BERT,需要尽快写一个C++版本的BERT服务。

不是那种用tfserving或者libtorch哦,是直接用C++写。

我面无波动地答应了下来,实则内心已经裂开了。

img

自己不是CS科班出身,压根没写过完整的C++项目,虽然有些Java基础,但到底几斤几两我还是蛮清楚的。

打比方的话,就是让第一次玩塞尔达、刚开完四个神庙、出了新手村的我直接去打盖农,悲壮之感难以言表。

P.S. 小伙伴们要的Cuda编程入门资料放在文末啦~

整个人都不好了

但我作为新时代的自强女性,还是开启了冲向海拉尔中心的旅程。

第一步,就是搜集可以参考的开源项目。

Fortunately,我找到了知乎开源的cuBERT项目,作者写得特别清楚,并且同时提供了GPU和CPU版本,但老板看了速度之后仍不太满意,最终我靠着极强的搜索技术又找到了英伟达刚开源的fastertransformer,用Cuda C++直接实现了transformer底层运算,速度秒杀其他方案。

在经历了各种make、install的折磨之后,我终于摸清了如何在服务器配置相关lib并运行c++代码,也顺利跑通了官方demo,性能完全符合预期。但不能高兴得太早,因为这个库只有transformer层的实现,前面的tokenization、embedding、pooling都没有写。。所以,这意味着我要读懂源码,然后自己把剩下的补全。

img

第二步,我开始读源码改项目。

这里有碰到了第一个难点,就是跑官方给的模型没问题,但运行我们自己的模型后就出现了 nan 这个恐怖的结果。于是我开始使用 print 大法,但惊讶地发现 cuda 底层全是并行的,一打日志都是乱的。。。于是我学会了 synchronize,在每个 operation 之后同步再打印结果,最终花了两天时间定位了问题:原来是Softmax没加溢出保护。立刻给作者提issue,不过在等待作者回复的过程中我居然自己给改好了,还默默学会了 Parallel Reduction 算法。

期间我还会卡在各种各样的事情上,经常会卡上一两天,陷入自我放弃的漩涡。

最终还是搞懂了源码,搞懂了cuda运算,并加上输入输出层搞出了完整的C++ BERT。

但仅仅有个程序还是不够,服务接口在哪里呢?

第三步,整一个服务。

于是我又搜啊搜,找到了一个宝藏:TensorRT Inference Server。当时的版本提供以下超赞的功能:

  1. 支持单GPU上的多模型&单模型多实例
  2. 支持多种backends框架(TensorRT、Tensorflow)
  3. 动态Batch增加吞吐
  4. 提供负载均衡及状态监测

所以又花了几天把C++ BERT适配TensorRT框架,成功变成了服务。

变成服务之后又有问题,就是每次换机器都要重新配置环境并部署,于是我又学会了docker,减轻运维负担。

通关了!

整个改造差不多耗时小两个月,也是我工作至今记忆最深的一段时刻。

我永远忘不了,那种看着看着代码就想站起来掀桌子的感觉。可以一起体会下:

template <typename T>
  __inline__ __device__
T blockReduceMax(T val)
{
  static __shared__ T shared[32]; 
  int lane = threadIdx.x & 0x1f; // in-warp idx
  int wid = threadIdx.x >> 5;  // warp idx

  val = warpReduceMax(val); // get maxx in each warp

  if(lane == 0) // record in-warp maxx by warp Idx
    shared[wid] = val;

  __syncthreads();

  val = (threadIdx.x < (blockDim.x >> 5 )) ? shared[lane] : -1e20f;
  val = warpReduceMax(val);

  return val;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

当然也忘不了身边同事牺牲自己时间给我的帮助,还有lead和我一起翻了半天C++ Primer 才解决问题的欣喜。

故事的后来很圆满,压测效果满意,成功服务了团队的BERT上线。包括后来我在20年初和其他两个大厂团队的人交流,都没有听到过更快的速度,甚至有同学直接质疑了我,因为他们的延时是我们的两倍。。。

去挑战一座山吧

现在回想起来,这段经历真的太宝贵了。虽然不想再经历一次,但自那以后我再也没怕过任何代码

做算法也有了底气,我可是搞过CUDA C++的女人,别叫我调包侠

如果想快速提升,那就去挑战一座山吧,找一个高质量的项目,读懂并进行修改,在一次次自我放弃中成长。

就像走过高考、走过考研、走过校招那样,过去那道坎就没什么了。



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

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

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

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

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

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

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

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

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

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

3w行,纯C。

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

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

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

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

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

\3. 接手一个完整的系统

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

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

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

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

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

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

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

\4. 设计一个完整的子系统

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

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

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

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

\5. 设计一个新的系统

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

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

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

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

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



先说结论:

1、一定要接触最好的编程体系,好的体系可以达到事半功倍的效果,否则即便智商再高,也有可能要走很长的弯路;

2、切勿有畏难心理,在学习的过程中会遇到数次平台期,期间有可能会怀疑人生,需要熬过去;

3、编程水平的提升需要经过大量的练习,不存在不劳而获;

4、要和优秀的人一起学,遇到不会的问题,要放下面子,敢于提问;

5、遇到不会的知识点,需要硬啃,今天不解决的问题,明天不会自己解决;

6、数学对于编程非常重要,请学好数学;

7、教别人会让你自己水平变高;

我是从初一开始学编程的,一开始学编程只是为了多玩会游戏。2010年在三线城市的普通初中,编程这个事情压根就没有普及,我也不知道学这个东西有什么用,那时就是学着玩呗。因为也没有人教,我就买了一本清华大学出版社出的Pascal的教材在那边瞎折腾。那时候网上也没什么资料,所以我学了三年啥也没整明白,像搜索、最短路这些算法我连名字都没听过,更不用说会写了。

进入了绍兴一中,我突然发现,原来编程不是我以前认为的那样子的,是另一个样子的。因为周围有一些很牛逼的人,就是那些能拿国内甚至国际奥赛金牌的人,我才意识到差距不是一般的大,他们五分钟十分钟能解决的问题,我自己搞了两三天都不知道在干什么,就只能拼命地学,每天压力也很大,因为周围的人都比我水平高,他们都是从好的初中过来的而我的初中水平差,我每天就担心自己会不会垫底,所以心态很不好,人就很焦虑。

我那时从初三暑假开始在绍兴一中学,一个暑假就学会了很多东西,因为有学长带着,就把动态规划、图论基本上都学会了。后来想一想好像我也愿意走这条算法竞赛的路,就继续学了。

我人生有三次编程水平大飞跃的时期,我的高中时期是第一次。但这次背负了太大的压力,因为世界第一次向我敞开了大门,我之前根本就不敢去想清华北大之类的学校,因为我的人生目标一直都只是考上一个一本学校,然后回老家做一个公务员。突然间,看到了不一样的希望,因为太想要,所以最后也得不到。每天就是失眠,两三点要嗑安眠药才能睡着。大冬天下着雪,我穿一件衬衫也会流汗,但我就在那边拼命地学,因为我相信努力还是能出成绩的。那时候确实也学到了很多东西,每天早上七点就到机房,晚上怎么也得到十点十一点睡觉,有比赛的话就要到凌晨两三点,第二天又是七点去机房,每天重复这样的生活,大概过了一年多的时间。最后高中我水平也比较高,小比赛都很牛逼,但由于心态的原因,一到大比赛就会全线崩盘,差点就没大学上了,也受到了很多的质疑,质疑我平时在作弊,因为我平时的水平和比赛的水平差距实在太大了。我受了很大的委屈,我从小就很看不起作弊这件事情。

最后我运气比较好,进了上海交大,进交大的时候,我心里其实是有一股气的。我觉得我要证明我自己,因为高中相对来说还是有点失败的。那我得告诉以前那些小瞧我的人,他们是错的。

很庆幸我进了上海交通大学,无论是从能力上还是思想上都极大地改变了我的一生。

大学的时候,比赛是三个人一队,有两个队友,每天都在一起学习一起训练,这样的道路就不会觉得太孤单,以前一个人的时候会害怕,总会患得患失,现在队友就是坚强的后盾,你就不会再恐惧,因为你们三个人是一个整体。

那时候我也学了很多的数学,因为高中的学习其实很多是建立在猜上的,很多都是靠直觉,直觉就是依靠多次训练之后锻炼出来的,你觉得它是对的,它也确实是对的,但就是不知道为什么。大学学了线性代数、数分等等之后,第一次知道这些为什么是对的,而不是仅仅只会用它们。这件事情让我养成了一个很好的习惯,就是写代码之前要从数学上证明自己的想法,这会让你在写代码、打比赛的时候犯更少的错误。于是我实现了第二次飞跃。

那时候,我和队友们经常一起睡机房,也经常半夜到处翻墙,因为管机房的大爷要赶我们,我们每天要和他打游击。但那时候的生活是快乐的,为什么呢?因为我心中有一个目标,我就是要去战胜世界上最强大的对手,去追求那种一览众山小的感觉,所以你不会觉得那是一种苦,相反你会觉得非常有乐趣。最后的结果说好也不好,因为各种各样的原因,最后到一半我自己就把这个事情停掉了,就去做科研了。

在这个过程中,我花了五年的时间,也慢慢地自己治好了自己内心的不安和焦虑,重新获得了小时候那种平静。最后,我也发现,我压根就不需要向世界证明什么,压根就不需要去打败任何人,我唯一想做的就是,去探索更多的东西,去探索自己的极限到底在哪里,我的人生没有那么多的观众,做好我自己就行了。

又过了几年,当我开始教别人写程序的时候,我的编程水平又实现了一次飞跃。在这个过程当中,我神奇地发现,我对一些基础的理解其实并没有那么深刻,所以就经常讲了一半会讲不出个所以然来,于是就迫使我重新回去思考,突然就发现,自己又能做一些以前做不到的事情,又学会了一些以前好几年都学不会的算法。那就是说,我以前学不会是因为自己对一些事情的基础理解是错误的。所以大家在学习的时候,也要把自己的想法和理解告诉别人,这对你来说也是一个检验和提升的机会。

还有,在学习编程的过程中,我自己遇到了非常非常多的瓶颈期,就是那种半年一年啥都没提高的状态,每天练练练就是过不了那道坎。最后其实发现,其实熬熬就过去了,编程水平的提升好像就是这样的状态,你缓很久,然后突然上一个台阶,然后又缓很久,再提升,如此循环。所以现在大家学不会也不要着急,再熬一熬,也许过一段时间就上去了。

回首往事的时候我觉得自己是幸运的,为什么呢?

第一,我确实遇到了一批世界上最好的人,无论是高中还是大学,大家因为共同的爱好聚在一起,每天不分日夜地去努力,在这个过程中互帮互助;

第二,我接触到了很好的编程体系,因为无论是高中还是大学,都拥有全世界最好的编程训练体系。我为什么对这个事情有很深刻的理解呢,因为我初中三年真的什么都没学会,初中三年做的事,高中一个礼拜就全都能做到了,如果我不进绍兴一中或上海交通大学,我可能一辈子都不会知道编程到底是什么、算法到底是什么;

第三,也是感谢命运给了我那么多的失败,让我非常早地就理解了,成功不是我追求的东西,我追求的是变成一个更好的自己;

第四,在过程中我也抵挡住了很多的诱惑,因为我的初中老师和我讲,我的天赋是低于平均水平的,但就是熬熬熬,好像把比我聪明的人都熬走了,因为他们都去做别的事情了,就我继续在干这个,好像熬一熬我也熬成了这个圈子里水平不那么差的人。所以我相信,很多事情是因为坚持,你才能够与众不同。天赋只能帮助你一时,但只有热爱和坚持才能帮助你一世;

第五,那时候我经常会死磕,经常下一个狠心,我不吃饭不睡觉一定要做完一个事情。如果没有这一次次的死磕,我想我也不会是今天这样。

后来,无论是科研也好工作也罢,我真的看到了很多很多东西,每天都抱着一种好奇心,想要对世界多了解一点,但如果不是因为遇到了编程,遇到了这么多非常优秀的人,遇到了这么多优秀的老师,我这样天赋的人是压根不可能走到今天的。所以,现在我们想把我们的好东西分享给更多的人,我们真的想要把自己了解到的东西开放出来让大家少走一些弯路。因为我们知道走弯路是什么样的感觉,我们知道那种苦涩。那么既然我们有能力,我们就应该帮助更多的人。我们后面做的很多事情都是基于这个逻辑。



断断续续的收到一些赞,写一些可能对大家有帮助的东西吧:

1、提高知识最好的途径是读书,包括但不限于计算机四大名著《操作系统》《计算机网络》《数据结构》《计算机组成原理》。经典书籍不仅仅有完善有效的知识,更重要的是这些书里的计算机经典思想,一直到现在都没有过时,十分的有用。

2、Github是个好网站,值得习惯性的到上面搜索需要的东西。比如awesome系列和一些质量很高的资料整理项目(整理常见的面试、刷题、常见工具链的git repo)

3、v2ex和知乎都是很好的网站(尽管审核方面被吐槽很多),论坛上有很多很厉害的大佬,关注认真答题大佬的动态对开拓知识领域是有一些帮助的。

4、善用搜索引擎(专指Google),最好能把自己最常用的工具的官方文档啃一遍。主要是习惯英文文档的表达方式+系统的认识自己所用的工具,对自己写文档也是有很多帮助的。

5、因个人有长期的抑郁经历,所以对心理方面关注得也比较多,十分推荐学习《哈弗大学幸福课》。这门课的综合内容十分丰富,实践性很强,能够有效的提高生活、职场中的软技能(沟通能力、抗压能力等)(这门课另外一个很厉害的地方在于,仅仅是上课的方式,也能提高你的逻辑思维能力,毕竟据说是哈弗学生选修最多的课,课程质量极其的高)。

6、有一个我自己打算做但实践得还不太好得地方:看经典开源项目得源码和架构。只看过一些小的玩票性质的开源项目,也学到了不少东西,大型的经典的开源项目还没能看(STL、Git等),这些项目对我来说主要是太庞大,时间上有些不够用。

7、最近在坚持做Leetcode每日一题,也推荐大家一起刷呀。保持手感,很多题看起来简单,但评论区也能看到有趣的知识。

8、关于职业规划这种事情,我以前是没有的(主要还是抑郁+低自尊影响的吧)。现在获取的信息太多太多,没有职业规划很容易被带偏。我是在做了长期的心理咨询+《哈弗大学幸福课》,工作、生活上都有一些经历了之后才慢慢想清楚自己将来的生活与工作要怎么打算。这种事情想清楚过后,做自己想做的事情目标会比较清晰,不会得过且过。



大概有三个时间点。

第一个是很久以前一个宁静的下午,我对着电脑屏幕发呆,因为我被分配了一个和地球正对面的团队合作的任务。而该团队代码之烂罄竹难书,回复速度之慢让我时常感到便秘。我还没有权限去check in代码和部署测试环境。一筹莫展之际我想干脆先去看看他们代码库把逻辑理清楚,之后能调试了改起来也快。

没想到我看懂了。一个破request在三个service之间弹来弹去的路径和副作用被我一下午读明白了。

当时我喜悦的心情约等于解了十个复杂的bug。

在这之后我打开了一个新世界的大门。无论是工作中的代码还是开源代码,各种工具库,系统底层,想看就看。

能够脱离调试环境深入理解代码这个能力的达成条件是长期独立解大型代码库中的复杂bug,磨炼自己对代码的感觉。有些答案说写代码是没有肌肉记忆的,有些答案说写代码是没有熟能生巧的,这些我是不同意的。学习编程即使走对了方向,也仍然需要大量反复的磨砺才能达到一定的高度。如果一个人还不能无障碍阅读代码,我是不承认ta有较好的代码能力的。

阅读代码的能力大概需要四到五年来培养,天赋较好的情况下,科班出身毕业一两年就应该已经有很强的阅读能力,而转行的在入行五六年左右也应该能够有这样的能力。

如果能大概一周时间在没有文档辅助下,允许每看懂几步去调试一下验证想法,能看懂Cassandra的写路径是怎么工作的,那代码阅读能力就算合格了。之后无非是更加娴熟和自然的问题,如果跨不过这道坎,那就还欠磨练。

第二个时间点是第一个时间点之后三年的一个冬日。

以前写代码的时候我都倾向于听Two Steps From Hell这种比较激昂让人想要骑狗上战场的音乐,沉浸在一种纯粹的释放的感觉中——因为我编程多数情况下实现只是在已经想好战略后的即兴创作。有几次一下午写千行上下的代码,十分酣畅淋漓。然而这一次,我突然想听Richter的悲伤小曲。

那一天我仍然写了很多代码,几乎重构了整个service。当我提交code review的时候,我很清楚地知道我的代码能力又提高了。因为我不再过多依赖我的直觉,而是有心地去衡量代码层面的权衡取舍。再去看之前写过的代码,有质朴的严谨和小聪明,却缺少了精巧有心的取舍和大智慧。

换句话说,从前我知道如何不写坏代码,但是这之后我知道怎么写好代码了。

这方面的磨练大概就是需要不断的review别人的code和被别人review,逐渐能够站在不同角度去看问题。同时阅读大量的生产代码以及开源项目也是必要的。“不坏的代码”是一个很大的解空间,要在其中选出“好的代码”来写,是需要持续的努力和耐心的。这里特别感谢当时的同事东欧大哥,他不留情面的code review和耐心跟我讨论我的review意见的过程使我受益非浅。

我在早年学习编程的时候读过《重构》这本鼎鼎有名的著作,它教会我如何不写坏的代码,并且能够把坏代码变成不坏的代码,对我影响深远。后来我读了一本叫做《A Philosophy of Software Design》的小册子,让我开始了对好的代码层面的设计的探索。

这里特别说一句,我个人是不喜欢设计模式这种分门别类的玩法的。我对它们的态度是去理解,但是实践中仍然从高内聚低耦合,可读可维护的原则出发思考代码结构。因为写好代码是一种在利弊之间权衡取舍的有创造性和艺术性的活动,抱着教条写不好代码,只能写出教条。

第三个时间点主要是涉及到对分布式系统的理解,因为题主问的主要是编程能力,所以就不细谈了。这部分主要是读书读paper以及读代码,动手推公式,动手写prototype。

最后强调一下:即使方向选对,即使平台不错,不下苦功,靠投机取巧,写不好代码。



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

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

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

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

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

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

说明:很多小伙伴都在问,就是抛出了现象没说每个阶段怎么解决问题,大家可随便评论区问问题,我收集完统一系统性回答。

没想到瞎写写这么多赞,谢谢大家!

01

近年来,有些读者会问我一些形形色色的问题,让我很难去回答,甚至给不出建设性的意见。

举个例子:

\1. 我学习什么能进入优秀的互联网公司工作?

\2. 我想做研发我应该学习什么?

众所周知,这问题就像你问学霸说你这么厉害一样让人难以回答。我作为一个双非软工本科学生,经过大学自己摸索和不断试错,毕业开始在百度从事研发工作。其实,我当时也有很多的疑惑,在这里给大家讲讲我的踩坑历程。

记忆中,我当年逛知乎、求助高人、甚至我的导师,都无法给出一个可操作的建议。除此之外,在我那种二本学校,知名企业都不会去咱学校校招,我和学长们对春秋招的概念微乎其微,进大厂是件很困难的事情,概率与踩狗屎不相上下。

作为探路者,求助知乎和论坛,给出的结论几乎都是好好学习数据结构/算法、现在大数据很火你应该学学Hadoop/Spark、你要是会微服务、docker、k8s一定会很加分。

让我想起了我当年问学霸题目如何解?学霸说:这个题目是来源于第X章第X例题,你这样解,答案就出来了,很容易的。至于为什么他能想到,鬼也不知道。

当时,我真的是花里胡哨的啥都学,啥都去倒腾,不知道是不是梁静茹给我的勇气。前端、后端技术栈、Hadoop/Spark、docker/k8s这些几乎都实操过,只是很多只是入门并没有深入研究,效果自然也十分有限。

这些概念,对于小白或者在校生来说,这仿佛在对说你不用学了,除非你天生技术欲望特别强烈。这对于大多数普通人来说,明显是劝退的节奏,可操行十分有限,几乎没有参考价值,不知道从何下手。

其实,道理是没有错的,多研究底层和热门技术栈是有益的。但是,脱离实际情况谈技术就是扯犊子,就像让中国男足拿世界杯冠军显然不符合实际,更应该是根据实际情况,做产出最大的事情,否则会信心全无。

接下来,我系统性拆分问题,在不同阶段应该「学什么」、「如何学」、「学到什么程度」,重点讲我当时遇到的问题,还有我是如何去思考的,最终如何解决的,思路比结论重要。

02

根据问题归类来看,主要在我自己的角度谈谈普通本科如何实现进入Top级互联网工作?

首先,说说在大厂工作都是些什么样的人,他们当年都是背着什么光环混进去的?

经过我的调研和分析,重点说一下在校招中面试官看中和考察的东西。

  1. 学历/专业、扎实专业基本功
  2. 有成果的科研经历
  3. 省/国家级软件设计大赛
  4. 丰富互联网公司实习经历
  5. 小有名气的开源项目经历

大概思路就是,要么你证明你令人信服的天赋如逻辑系统思维、聪明,让人觉得你可以被快速培养;要么你有丰富的工程实战经验,证明你具备优秀工程师的潜质。

当然,你可能会说这么多要求,恐怕神仙也做不到啊,简单太苛刻了。在这里,并不是上述要点全部满足,只是满足其中两项证明你的实力即可,毕竟面试时间十分有限必须有点让人信服的东西啊。

举个例子:

1、假设你是上海交大、华中科大大学毕业的学生,你可能只需要重点复习数据结构/算法等专业知识,辅之把学校的科研经历说一下。可能进入什么阿里华为百度问题都不是很大,专业知识对于你们来说自己不再话下,毕竟考理论就是你们的特长。

2、假如你是双非大学毕业的学生,那么你必须用国家级大赛、开源项目、互联网公司经历证明自己。总之,多做项目,专注于技术本身,让自己更早具备职业软件工程师的实战技能。

简而言之,你没有光环,那就比别人多努力点,提前做好职业规划,把时间投入技术本身不要投机取巧。

03

鉴于上述分析,知道需求是什么?对于我们来说,主要把精力投入在技术本身。

接下来,我们将面临一系列问题。 1. 我应该做什么方向?(方向) 2. 我应该学习什么内容?(规划) 3. 我如何学这些内容?(方法/策略) 4. 我应该学到什么程度?(量化) 5. 如何把理论用到实际项目/产品中?(产出)

不同方向,意味着不同领域不同,学习的知识和实战项目有共性也有差异。在这里,我主要讲一下通用的思路。重点拿我擅长方向举例,其他方向可按照同样思路举一反三。

根据我的经验,可将内容分为原理、应用、擅长方向三个纬度。原理和应用纬度必须学习,方向纬度根据自己擅长方向深入学习。

img

原理:计算机网络、操作系统、数据结构/算法,这些东西都是专业课好好学即可,数据结构/算法可以偶尔刷题。校招的时候再重点复习,初级阶段不必花太多时间深究。

应用:它是最基础的内容,不管你从事什么领域都将离不开它们。这也是小白入门重点花费时间的地方,你将在这里不断与程序斗争如调试、验证、异常、解决。

方向:不同方向本质上就是在基础应用上扩充,发挥它们擅长领域和特性去解决特定问题。在这里,简单列一下涉及的技术栈。

  1. 后端开发:消息队列、缓存、rpc、微服务。
  2. 大数据开发:Hadoop、Spark、Storm、Flink
  3. 自动化运维:elk、ansible、zabbix、docker、k8s

04

基于上述分析,主要讲了整体思路,大家可能会觉得有点不太好理解。接下来,拿我当时遭遇的处境进行举例阐述,这样让不同水平或时期的同学有不一样的体会。

假如有时光机让时间往后倒退3年,时间来到我刚上大二的时候,作为一枚小萌新开始学习JAVA走上后端开发之路。

对于我来说,操作系统原理、计算机网络先战略性放弃,毕竟刚接触编程,看高大上的原理,每次上课都想睡觉。当然,数据结构/算法我还能好好听听,毕竟我数学功底还行让我不排斥。

为什么不先学习基础性原理?
举例:假设你学骑自行车,你是直接上去就蹬?还是先把轮子拆下来研究清楚原理再去学习怎么蹬?

重点:根据我的经历,在新手阶段不管是接触新的语言,还是新的方向。最快的方式就是先把自行车蹬起来,等你蹬熟练了再去研究轮子是怎么造出来的。

根据上述策略,刨除我踩的一些坑,我把学习征途划分四个阶段,实现学习效率的最优解。

img

第一阶段:新手入门

在我入门的时候,我遇到的最大困难是代码不会写,DEBUG不会做,程序报错不会看毫无头绪,甚至大家常说的百度一下的关键字我也不知道搜。

这时候,最大的目标就是根据百度/查文档/看视频,把程序调试出预期结果,甚至你抄代码都行,很多时候抄代码你都不一定能DEBUG出预期结果。这就是现实,主要就是要把对编程的排斥消磨殆尽。

这个阶段,不需要太关注底层实现原理,最重要的工作就是把应用层面的技术,不断练习直到熟练掌握上面提到的应用纬度「 编程语言、Linux、数据库、HTTP网络协议 」。

  • 时间:3-6月
  • 目标:会调试、会查文档、会用搜索引擎
  • 内容:JAVA基础语法、MYSQL数据库、Linux操作系统、HTTP通信协议
  • 方法:只关注如何使用技术,难以理解的背下来,不关注底层原理。
  • 成果:实现常见的管理系统模块,能部署在服务器上,供他人访问。

对于现已从事计算机行业的同学,其实这部分内容非常简单,可能按照正常水平少则几天,多则不超过一周就能开发出简单模块。简单说,它顶多是普通本科毕设设计水准,主要是让新手在感官上体验软件产品。本质上,在计算机世界里,抽象来看就是数据的计算、传输、存储。随着你的经验增多,你会发现很多技术都是诞生或优化性能都是在解决计算、存储、传输的问题。 在这里,主要让大家在系统的角度感受最简单、最初级的技术模型。

img

  1. Linux操作系统:承载应用程序、数据库的运行,提供CPU供应用程序计算。
  2. 应用程序(Java/Python/Php):JAVA主要采用Servlet、JDBC承载网络的传输、数据库连接管理。
  3. 数据库(MYSQL):主要理解关系类数据库的存储,对数据进行操作。
  4. HTTP/TCP:熟悉重点网络协议,它分为包头/包体进行传输,包体格式可能分为form、json、pb、二进制。

作为小白,我们不得不面对一个现实,小白阶段中大多数人对计算机了解几乎为零,尽管你小时候玩游戏贼牛逼。就像写个HelloWorld,你起码要安装好环境,安装好IDE,可这简单的两步都能捶死在坐的各位弟弟。

幸运的是,我们在互联网如此发达的时代,市场如此火爆,视频资源可以随便搜索,甚至自动给你推荐。

我是特别推荐这个时期,大家去完整找一套视频来系统学习。尽管新手视频对于现在的我来说很费时间,但是对当时小白的我来说,这是新大陆,它能带你简单过下计算机体系导图。我在课余时间学习视频,让我在课堂上学习理论的时候,能够有豁然开朗的感觉,自然就比别人强了。

在这里,我就简单给大家推荐一些学习资源。

假如你学习java,推荐你去尚学堂/尚硅谷/网易云课堂,它们会有成熟的学习路线,视频也是那种手把手敲的,新手学习比较友好,我狂喜的是可以不投币白嫖。

假如你学习python,你可以看B站/廖雪峰的视频,自行搜索。唯一不太好的是,这部分课程路线设计比较模糊,学习内容有点大而全,小白有筛选成本。

我个人感觉百词斩旗下 的「夜曲编程」还不错,当时我想快速学习做下python做数据分析和统计,提升分析数据指标效率。同时我时间集中学习时间有限,偶然看见「夜曲编程」入门免费课程试了一下,1-2周学完就用到工作上,确实写脚本还挺爽,减少了机械化的工作。

  • 知识点模式继承了百词斩优点,生动有趣,简单易懂,不枯燥。
  • 移动端卡片式学习,随时随地学,利用睡前15-30分钟碎片化学习下,减少我玩抖音等视频时间。
  • 提供清晰的学习计划、打卡、课后练习,每天看1-5节,也就几个星期就学完了。

关键是可以领取20天免费课程,免费领取方式:下载「夜曲编程App」 手机激活就搞定了。

第二阶段:项目练习

通过第一个阶段学习,你对编程从一无所知到有所斩获,对计算机世界充满了好奇,甚至有所开心。这时候,你最应该做的就是去满足你装逼的梦想。

假设你是爬虫方向,你应该去爬表情包、爬知乎数据、自动抢票,去满足你无数个装逼梦想。

假设你是算法方向,你可以去研究推荐算法、图像识别模型,去做个商品推荐、人脸识秀一秀。

假设你是后端方向,你可以去研究下网络编程/网站开发开发个仿微信聊天应用,体验下lowB版微信。

画外音:多做项目,坑是一步一步踩出来的。

作为大学生,实验室、软件设计比赛、开源社区都是你发挥现象力的天堂,这些倒腾的经历将是你毕业时最宝贵的经历。

第三阶段:强化理论

经过前两个阶段实践,时间来到大三,这时候基本的软件开发已入门差不多达到普通培训班毕业水平。同时,专业课如数据结构/操作系统/计算机网络也上的差不多了,对概念多多少少有初步了解。

这时候,你会发现很多原理你不懂,将很难更上一层楼。

  • 你不知道使用ArrayList还是LinkedList?
  • 你不知道为什么要使用线程池
  • 你不知道为什么分层设计使用分布式场景?

你将处于写代码一时爽,一直写一直爽,遇到性能问题直接土崩瓦解。所以,你不得不去学习理论知识让你走得更远。

问题:为什么在这个阶段强化理论知识?
在新手阶段去强化理论知识,会让你兴趣骤减且产生学了有何用的错觉。同时,这是最好的时机,学校专业课学完你有基础概念,你有实际软件应用场景,这些东西让你深挖理论的时候会快速给你构建起基础图谱,让你兴趣激增不断体验学会的东西,将戳痛你最痛的神经,瞬间把你以前遇到的问题有新的认知,这就是答案。简单说,面向问题,解决问题,让你实实在在感受到成长,这就是成就感的力量。

问题:如何高效的学习理论?

img

其实,编程语言和计算机基础都是相通的,只要你学透一门编程语言剩下的就大同小异。当然,计算机基础毕竟是枯燥无味的,学习毕竟是有方法的。

举个例子:

站在编程语言的角度,你用心去总结,你会发现不管什么编程语言,变来变去都是换了个花样在谈以下内容。

  • 程序结构(数据类型、控制语句、面对对象、异常处理)
  • 集合(list、set、map)
  • 文件操作、网络通信(io、bio、nio)
  • 线程、线程池

不管在面试还是技术探讨,重点考察的都是集合、网络通信、线程/线程池。源自于它跟计算机基础有紧密结合,你要优化它们你必须具备扎实基本功。

基于我的研究经验,我建议大家在学习计算机基础的时候,不要因为理论而理论。你应该去通过编程语言源码去学习计算机基础,只学你当前认为最重要的。

举个例子:

当我去学习数据结构/算法的时候,我会一边学习源码一边思考数据结构,这样就让我有实际应用场景不会因为理论而理论。我学习list、set源码的时候,我就学会链表、栈。我学习map的时候,我就学会了红黑树、散列表

当我去学习计算机网络的时候,我会一边学习socket的用法,学习Linux网络通信模型epoll,这样就重点把网络协议学会了。同时,很多应用场景极少的理论知识,我就粗略记忆或者跳过,这样就节约了很多时间。

当我去学习线程/线程池的时候,我会学习锁机制、生产者/消费者模型这些操作系统原理的重要知识,跟编程语言中关联不大的我就粗略记忆。

第四阶段:深究专长

经过前面三个阶段的学习,你已经具备扎实基本功和项目实战经验。接下来,你需要做的就是更加的专业化,研究一些有生产意义的东西。如果你一直写学生管理系统,这些没有价值没有意义的东西,那么毫无意义。

这时候,你应该去互联网公司验证你学习的技能。除此之外,你可以去学习额外的成熟先进技术栈。这样,你就有实际业务经验,就有技术的宽度,同时又有深度,这就是你核心优势,毕竟算法/数据结构这些东西在竞争的时候大家都会。

画外音:去实习,最好去大厂实习,接受互联网软件开发的挑战。要是不能,那么去研究实际企业技术栈的应用与底层研究。

举个例子:

假设你是后端开发,你就可以去学习微服务的技术栈,springboot、dubbo、docker、hadoop都可以去学习。除此之外,设计模式,redis原理都可以去学习研究,只有这样当你去面试的时候,你有很多话题和故事讲给别人听,你的专长研究既可以让你说业务场景,你又可以讲底层原理,对答如流。

05

经过上面的训练,已经具备了解决问题、快速学习、编写代码能力,也就是具备软件工程师的职业素养和扎实基本功。

这时候,进入互联网公司开启职业道路,你将会很快有产出,不会陷入徘徊自闭的状态。更何况,你的职业素养已经能够让你遇到问题,能快速的学习克服困难。但是,要是让你去参加面试可不一定能独善其身,毕竟工作拧螺丝,面试造火箭可不能疏忽大意。

接下来,重点讲一下如何应对面试?

面试也就是把自己卖出去,让别人觉得你值。简历是至关重要的环节,所有的知识和技能全都是围绕它展开,否则毫无意义。因为在面试中,面试官关心你有什么,也就是面试完全围绕着你会的东西展开提问,所以你就把你的优势发挥到极致就行。

环节一:准备简历
简历一定要认真对待,一定要简介精炼,尽可能把内容压缩到一页,毕竟简历筛选就30秒不到。这时候,简历排版、简历字体、简历模板都有讲究,细节决定成败。

在写简历的时候,主要分为个人资料、实习经历、项目经历、专业技能。其实,没什么技巧,参考STAR原则,重点体现你在项目中的价值和思考。

  1. 要体现做了什么事情?
  2. 遇到什么困难?
  3. 怎么解决的?
  4. 产出是什么?

假设有读者需要简历模板,可关注提供给大家。

环节二:梳理知识体系和刷面经
以前,学习知识是零散的,学习策略更多是面向解决问题,以至于知识不系统,表达逻辑层次有限。面试官逻辑思维强,所以你必须做好充足准备才能脱颖而出。

最好的策略就是梳理知识体系和准备面经,我们都知道要是你面试官问的问题是你刚好熟悉的问题,你岂不是轻松闯关成功?所以,准备考纲、梳理知识体系、疯狂刷题这就是最好的策略。

按照互联网面试流程大多数分为三轮面

一轮面试:主要是考察计算机基础知识和擅长语言基础知识,重点考察数据结构/算法、网络编程、擅长语言基础。但是,绝对不是死记硬背的东西,一定是深度和广度紧密结合,环环相扣直到把你肚子里的东西全部挖出来。

举个例子:

  1. 获取链表倒数第N个节点的值,只许遍历一次。
  2. 有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1M,返回频数最高的100个词。
  3. 谈谈HashMap,说下它们的数据结构?
  4. Key在HashCode取余以后,它可能全部堆积在某几个Key对应的链表上,这样就会造成该数据结构存储或者查询低效,那怎么解决呢?
  5. 为什么会链表要变成红黑树,什么时候从链表变成红黑树,什么时候从红黑树变回链表?
  6. 假设多个线程并发访问,那可能造成容器更新或者操作出现问题?
  7. 除了使用synchronized加同步锁,还有没有其他办法解决呢? 8. 为什么采用CAS,能说一下ConcurrentHashMap的具体实现吗?

你会发现每个问题都是环环相扣,从简单到难,目的就是挖掘出你的极限。大多数情况都是,从数据结构/算法入手,扩展到编程语言特性,再扩展到并发/网络编程不断进行深挖。当直接问实际用法应试者答不出来的时候,就会再次引入到计算机基础知识,这样不断反复调度试探应试者的是深度和广度。

二轮面试:这轮考察实习/项目经历,重点考察你的面试储备。众所周知,大部分应届生项目经验十分有限,大多数是图书馆管理系统、电商系统这样。重点说一下应对策略,可以去网上找你做的项目可能遇到的领域难题,去找解决办法,最终扩展补充到你的项目中。

三轮面试:这轮面试更多是经理考察应试者的基础能力。也就是逻辑思维、抗压、时间管理等基础能力,看下是否能融入团队,毕竟适合团队的才是最好的。

这里主要讲了思路和应对策略,至于篇幅有限,面试题只能读者自己梳理,假设有需要后续再聊。大体的思路: 1. 梳理知识体系看面试可能考哪些东西? 2. 去网上搜寻和整理面试题? 3. 把数据结构/算法、并发编程、网络编程串联起来,还要学会理论知识和实际实战中来回串联。

总之,作为普通学校的同学,你只有花更加多的时间在项目实战中,实习/打比赛/逛开源社区,这些时间让你更快接近成为职业软件工程师。当机会来临的时候,你抓住机会就踏入大厂的大门了,幸运永远不会无缘无故眷顾你。


5月24日,读者问题解答更新:

经过读者提问,再附之我的思考,我大概总结出来分为这么几类问题。

  1. 计算机专业需要学什么?
  2. 找工作,那些计算机专业课学了有用?
  3. 学不会,我到底适不适合学编程?
  4. 找工作有那些方向,我应该选择什么方向?
  5. 专业课和课外编程学习,如何权衡时间?
  6. 学历普通,我到底是找工作还是考研?

不卖光子,直接说下整体解决思路。

  • 对齐认知:计算机学什么。
  • 学习方向:确认学习方向。
  • 执行路径:具体学习内容。
  • 学习答疑:如何坚持下去。

3.1 对齐认知:计算机学什么

问题:那些学了有用?

有用:计算机理论(算法、网络、操作系统)、项目、实习。

企业招人就一个目标:来了公司能干活,培养完能干活。

软件研发这职业,像奖学金、三好学生、学生会主席、英语四六级,对于咱们这职业来说用处不大,有只是能彰显有亮点可作为加分项,锦上添花。当然,你能去拿到这些东西尽量去拿,毕竟别人能拿到,你拿不到你怎么证明你比别人强?

3.2 学习方向:确认学习方向

前端、后端(产品或架构)、测开、运维、大数据开发、数据分析

3.3 执行路径:具体学习内容

从大学时间角度,每个学年会拆分出目标。

img

从专业知识角度,根据不同解决学习不同知识。

img

总的来说,实际操作起来还算清晰。

阶段一:找培训机构视频学习,只要能独立实现可让人访问的应用如仿微信聊天软件。

阶段二:做项目,你可能会学习崭新的技术栈(springboot、redis、kafka),需要什么学什么。

阶段三:通过做项目使用了很多新兴技术,计算机理论知识也学了很多。这时候,你核心目标就是把学过的东西总结归纳,拿着他们去面试找工作,这时候你要能说出怎么用,还要说出为什么要用。

开源学习网站:

要是觉得还得写不错,点击

@码农皮邱

关注,有惊喜!



按照时间线走:

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

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

开始用 Github

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

自己写点小东西。

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

学习理论知识

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

读源码并不难

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

img

img

学习核心专业课

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

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

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


在看这个回答的小伙伴们,如果你还是编程新手的话,计算机基础也几乎为零,那我建议先找一些简单的,易于上手的在线课程来学习,比如最近很火的「夜曲编程」,它们旨在降低编程的学习门槛,不管是写代码还是学习知识,都在线完成,并且不断的给予正向反馈,按照他家的学习方法来,进步还是看的见的,能少走很多的弯路。

img

还能有很多大量的题库,可以练习,这些出题的都是以解决实际问题为导向的,还挺有意思的,在线进行编程练习:

img

没有了前期搭建环境的各种问题后,上手编程会变得容易很多,你也更容易进入到良性循环中,培养编程的自信心~

包括现在也能在他家的公众号回复「免费教程」然后获得免费学习的扎实课程,虽然是体验课 感觉内容还是毫不敷衍。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/111905
推荐阅读
相关标签
  

闽ICP备14008679号