BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #52842同步于 2016/9/12
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

[随笔+吐槽]数据结构+算法vs语法 btw:培训班vs CS专业

lhy963
2016/9/12镜像同步37 回复
先听一个故事。(略有文学上的加工) 近日,LZ的朋友A君问了这样一个问题: 请分析下列代码的执行逻辑。 (代码是凭借记忆写出来的,可能顺序上有些错误。但意思肯定是对的) ``` public class LoadTest { private static int static1=10; private int i=20; public LoadTest() { System.out.println(++static1 +","+ ++i); } private static LoadTest l1 = new LoadTest(); static {static1=100;} private static LoadTest l2 = new LoadTest(); {i=200;} public static void main(String[] args) { LoadTest l3 = new LoadTest(); } } ``` 于是我从ClassLoader开始分析,然后静态语句块,构造函数,main方法等逐行进行分析。 A君困惑不解,围绕着静态代码块,动态代码块,全局变量,构造函数的执行顺序以及内在逻辑问个不停,然后一直问“能解释的再细一点吗?” LZ的忍耐终于突破了极限(因为这类奇葩代码的输出他问了至少三段了)…… 于是我回应道:“学好编程的核心是算法与数据结构,而不是掌握多深奥的语法,理清多奇葩的代码。” “衡量编程好坏的重要性之一就是代码的可读性,此段代码就已经严重违背了。因为你困惑的根本就是`private static LoadTest l1 = new LoadTest();`里面出现了类的实例化,又恰巧是此类本身。就算实际工程中真的需要这样的场景,你在`private static LoadTest l1 = new LoadTest();`里面new个别的类,思路不就豁然开朗了吗?” “没有算法和数据结构能力的程序员,只会调用API和连数据库写一点crud,那有什么用呢?” A君茫然道,“算法,数据结构,API……这些词语我去百度下。” LZ说,"我想你既然是Java的初学者,在学习的过程中一定练过很多解决“实际”问题的练习题,你做过吗?” A君语速陡然加快:“我做过,判断闰年,找水仙花数,判断一个数是不是素数,打印九九表,解一元二次方程,猜数字游戏……” LZ会心一笑:“那请你说说怎么判断一个数是不是素数。这就是一个算法。” A君依然神情得意:“这个我会写,for循环就得了~” A君兴致勃勃的敲起键盘来,下述代码跃然于屏幕上。 ``` public boolean isPrime(int n) { if(n==1||n==2) return false; else { for(int i=2;i<n;i++) if(n%i==0) return true; return false; } } ``` LZ心里暗自汹涌,新手就是新手啊。于是LZ接着说,算法质量优劣的重要指标是其复杂度,简而言之就是速度。你看你这个`i<n`是不是没必要,只需要试探到$\sqrt{n}$不就可以了么~ A君思考了一番道,“逻辑上是没错啊,可是Java里面如何写根号?” LZ已经彻底抓狂了,“就算老师没教你Math.sqrt(),你完全可以写`i*i<=n`嘛~!” LZ面色凝重,正经脸的说道:“其实这就是你要锻炼的,你现在意识到你这方面的能力完全为0,甚至为负。这些代码没有一段是形如`i+=(++i)+(i--)`这样稀奇古怪的代码,它却训练你的编程思维。” A君:“逻辑思维吗?那不还是要多做题吗?所以我先把老师留的50道选择题刷完。” LZ:“其实是你的编程思维,或是说算法能力。选择题是为了应试而生的,你学习编程为的是实际开发,而不是去答考试卷子。Leetcode个人认为是新手锻炼算法思维的好去处,又是直接面向于找工作的试题。” A君:“可是我语法还没学完,static,final,abstract,implements这些东西还没理解透,够做吗?” LZ表示无力吐槽。。。。。。 --- 华丽的分割线之后是lz的一些个人看法。 其实尽管如今有各种各样的开源框架(如Java的SSM,PHP的laravel,symfony,yii等)、各种功能强大的API(如Java中的各种集合类)、甚至语法简洁明快易于上手的语言(php,python等)都能大大减低开发难度,但依然不能否认算法和数据结构的重要性。LZ觉得**会写代码**和**写的好代码**的区别就在于数据结构和算法的功力深浅。举个例子,任何人都学过线性表(数据结构的第二章好像就是它),但线性表分为数组、链表,甚至还有衍生出来的跳表(SkipList),何时在何种场景下选择何种数据结构是最恰当的?这显然不是Java语法中能传达给你的知识,而这种需求在实际开发中确是十分重要的。 算法其实是提高解决问题能力的途径,面对一个输入和一个期望的输出,怎么能够最合适的(未必是最快的)解决它?例如上述的判断素数的算法,(先抛开Miller-Rabin算法,那东西对编程新手来说,接触不到也很难理解),A君的复杂度为O(n),LZ修正后的**朴素算法**为O(n^1/2),试想n为一个非常大的数,时间上会差了多少数量级。 再考虑下一个场景。某开发者一直在写Java,但是业务需求必须用python实现,那么如果精通数据结构的Java开发者,从头开始学习python效率肯定远高于一个只懂java语法只会调API的人。 因此,LZ斗胆认为,数据结构与算法是基础,是核心,往往是编程高手与新手的根本差距所在。**尽管有很多开源框架简化开发,但依然要重视数据结构与算法。** --- 华丽的分割线之后是人设的介绍。 LZ:我邮妓院研二渣一枚,在实验室的项目是java实现的,数据结构基础还算不错,但Java功力比较渣,所以大神勿喷。 A君:楼主高中的前桌,炒鸡炒鸡要好的朋友。毕业于某985高校物理专业,可能是专业选的不适合自己吧,自去年毕业起失业至今,如今想转型做Java程序员,目标是【10年努力进入BAT】。现在入职了一家lz家乡(省会,二线中等城市)那边的外包公司,先接受入职培训,学费1W5,培训时间四五个月,学习html,java,spring,android,号称是培训后接受考核,成绩优异者写代码,成绩一般者在软件公司做文职工作。目前A君迫于生活压力,学习热情颇高,但长期陷入奇异代码的探究未免给楼主一种程序员版孔乙己的感觉。 有人问lz说这么多想表达什么, 一是吐槽钻研奇葩代码这种学习方法,因为在实际工程中肯定没人这么搞; 二是反思及探讨,学好数据结构和算法(亦包括计算机网络,数据库,软件工程等cs常见的专业课)对用高级语言开发工程有多大帮助,以及cs专业学了4年乃至6-7年的程序员与4个月培训班速成出来的人有多大区别? 当然也是希望大家给lz一些建议,毕竟是朋友,lz不希望一个新手陷入误区[/md]
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
cocoyimasa机器人#1 · 2016/9/12
妓院研二渣硕,可以可以
lhy963机器人#2 · 2016/9/12
自顶求十大
shd110110机器人#3 · 2016/9/12
顶顶顶起来
jellyjiao机器人#4 · 2016/9/12
bd
Ratio机器人#5 · 2016/9/12
bd 【 在 lhy963 的大作中提到: 】 [md]先听一个故事。(略有文学上的加工) 近日,LZ...
Ratio机器人#6 · 2016/9/12
BD 【 在 lhy963 的大作中提到: 】 [md]先听一个故事。(略有文学上的加工) 近日,LZ...
lhy963机器人#7 · 2016/9/12
妓院研二狗在一个月培训班喵面前被问的体无完肤 【 在 cocoyimasa 的大作中提到: 】 : 妓院研二渣硕,可以可以
zwbsdu机器人#8 · 2016/9/12
楼主吼啊,我是计院研一的,可能以后也是要用java,但是本科技术较渣,以后希望能和楼主多多请教
FromSixToTen机器人#9 · 2016/9/12
恩,就是这样,某些认可吧。 @nuanyangyang @wht