返回信息流先听一个故事。(略有文学上的加工)
近日,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]
这是一条镜像帖。来源:北邮人论坛 / java / #52842同步于 2016/9/12
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
[随笔+吐槽]数据结构+算法vs语法 btw:培训班vs CS专业
lhy963
2016/9/12镜像同步37 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复