实验室集训已经有很多次了,可是并没有什么资料所留,所以我想把我们要讲的东西以博客形式记之,并收录为一个系列。不仅是为讲课之便,更是为后来者留下珍贵的资料以作参考。
希望实验室日后能越办越好!
在讲课的开始我觉得了解一下程序设计语言的发展简史是很有必要的,因为只有知道一项技术的来龙去脉,才能理解这项技术的一些设计和思想。语言也是如此。
我们今天接触到的程序设计语言都是图灵完备的。这里的“图灵完备”指的是语言指定的数据操作规则能够实现图灵机的全部功能(图灵机的概念是由阿兰·图灵提出的,图灵机为计算机能够解决的问题划定了一个边界)。所以,图灵机是所有程序设计语言最底层的模型,程序设计语言都是在这个基础上生长出来的,包括众所周知的计算机基础:用 0 和 1 编码。
我们今天的计算机能够识别的都是 0 和 1,但真正用 0 和 1 直接写代码的人少之又少,因为实在太麻烦了。所以,早在计算机诞生之初,就产生了汇编语言,它可以将那些 0101 的操作符变成更容易记住的 ADD、MOV 之类的指令。
相比于 01 串,汇编虽然进步了一些,但人们很快就发现,用汇编写程序也是非常痛苦的事情,因为只有对计算机了如指掌,才能写好汇编。更可怕的是,即便你熟练掌握了一种计算机的汇编语言,换成另外一种计算机,你也必须从头学过。
这时,就轮到高级程序设计语言登场了。
PS:思考一下,如果设计者是你,你会怎么去解决这个问题?
第一门被广泛使用的高级程序设计语言是 Fortran,它为程序设计语言的发展奠定了基础。比如,一些基本控制结构出现了,数据开始拥有了类型(类型就是一种对内存数据的解释方式)。虽然这些东西在今天看来非常简单,但和那个年代使用的汇编相比,简直是一个巨大的飞跃。
Fortran 对于计算机的发展起到了巨大的推动作用,人们也逐渐认识到高级程序设计语言对于开发效率的提高。接下来,人们开发了各种高级程序设计语言,不断地探索怎样写好程序。
早期程序设计语言探索的集大成者就是 C 语言,它提供了对于计算机而言最为恰当的抽象,屏蔽了计算机硬件的诸多细节。时至今日,C 语言依然受众广泛。
随着高级程序设计语言的发展,门槛逐步降低,人们可以开发的程序规模也逐渐膨胀。这时候,如何组织程序成了新的挑战。有一种语言搭着 C 语言的便车将面向对象的程序设计风格带入了主流视野,这就是 C++。很长一段时间内,C++ 成为了行业中最主流的选项,既兼容 C 语言,又提供了很好的程序组织方式。
虽然各种高级程序设计语言已经屏蔽了很多细节,但有一个问题始终没有得到很好的解决,也由此引发了更多的问题,这就是内存管理。其实,人们早就在尝试各种屏蔽内存管理的方式,但因为早期计算机硬件性能有限,所以没有任何一种方式能够成为行业主流。
后来,计算机硬件的能力得到了大幅度提升,这让那些在废纸堆里的技术又焕发了新的活力。这个阶段的胜利者是 Java,一方面,它支持面向对象编程;另一方面,它还有垃圾回收机制——一种内存管理的方式。
Java 的路其实也很坎坷,因为它早期在个人电脑上的尝试并不算成功。后来选择了企业级开发的赛道,才有机会展现自己的优势。因为企业级服务器本身性能优于个人电脑,对 Java 有更高的容忍度,它才得到了机会,不断进行自身的优化。
当硬件不再是程序设计语言的发展障碍之后,程序设计语言又该如何发展呢?
从前面的历程不难看出,程序设计语言的发展就是一个“逐步远离计算机硬件,向着待解决的问题靠近”的过程。所以,程序设计语言接下来的发展方向就是探索怎么更好地解决问题了。
语言学习是一个老生常谈的话题了,相信大家在面对语言学习时都犹豫过,不知道该如何选择语言。一会听这说Java语言用的人多,好找工作;一会又那听讲Python很火爆,Python是未来;而自己上各种论坛,又听到别人说go语言也不错…
我估计大部分初学者都会经历上面场景,而知乎上出现诸如“Java值不值得去学习”,“Python好不好学”此类问题也不足为奇了。
其实啊,当你问出这种问题的时候,大家都明白了你是个新手!
真正的大佬是不会去纠结哪种语言好学,哪种语言厉害。他们并不会说自己最擅长的语言天下第一之类的话,因为语言在他们眼里只是一个工具而已。
而这也是我想告诉你们的内容之一——语言只是一门工具。
千万不要被语言所束缚,不要因为你学了一门语言就觉得那门语言天下第一,而不愿去接触其他语言。
PS:为什么说语言只是一门工具?
那么,在这个日新月异的时代,面对浩如烟海的程序设计语言,我们又该如何去选择学习一门语言呢?
首先啊,你得明确你想干什么,上面也说了语言只是一门工具,既然是工具那必然是有优缺点的,也有自己擅长的领域。
比如最近很火的Python,Python擅长的领域是大数据、人工智能以及网络爬虫,那你如果想做这些事情,Python就是个不二之选。
不仅是因为它简单易学,也在于它在这些领域有着较为完备的生态,这个很重要,你学到后面就能深深领会这点。
但其实Python也没有像现今有些媒体吹的那样好,现在的热度很大程度上是培训班炒作出来的,如果说你只会Python,那么你就得思考思考自己未来的方向了。
目前来看,只会Python是找不到工作的,除非你是往人工智能方向,大数据方向发展,但说实话,如果仅会Python,你的路也走不远。就正常开发而言,Python仅仅只能小范围使用,无法当做主流语言写进项目。
再比如我们今天要讲的Java,Java擅长的领域是服务端开发。
何为服务端开发?
这个概念是相对客户端而言的,比如我们的手机电脑以及各种终端,这些都是客户端,而服务端则可简单理解为我们所说的服务器。
Java虽然没有c语言那么快,也没有c++那样能直接操作内存(既是优势也是劣势),但是Java有着自己的优势,比如“一处编写,处处运行”的跨平台机制,还有内存管理机制等等。
当然最大的优势在于Java有着其他语言远不能及的生态圈,可以说这是Java蝉联语言榜高位的重要凭借。Java的生态太好了,你写个项目,人家各种轮子都给造好了,你只需要去用即可,你说这样的语言能不爱吗?
至于大家都学过的c,这门语言到现在快50年了,这在IT界是个极其长的时间了,而c却经久不衰,可见它的影响之广。c语言相对于Java这种语言来说。更加接近机器,虽然缺少面向对象,缺少组织大规模项目的能力,但是无论是在嵌入式开发还是语言入门方面,c语言都是个不二之选。
当然语言不止以上说的这些,还有诸如擅长云计算、擅长中间层的go语言,还有安卓开发的新宠kotlin语言,还有flutter框架必学的dart语言等等,感兴趣的同学可以去多了解了解,毕竟这个世界远不止眼前的Python和Java,还有很多值得我们去学习的语言。
PS:谈谈你了解的或者听说过的语言有哪些?
总之,你学习哪种语言取决于你想去干什么。
上面我们谈了那么多语言,不免让我们眼花缭乱,心生畏惧。
其实大可不必,因为语言本质是相通,都是一种抽象和封装,回顾我上面所说的程序语言发展简史,我们不难发现语言都是建立在机器指令之上。
而语言呢,不是让我们能做什么,而是让我们不能做什么。
说到这点我们就要谈谈语言的编程范式
PS:以下这些分享大多摘自极客时间里的《软件设计之美》中编程范式章节。
编程范式(Programming paradigm),指的是程序的编写模式。使用了什么编程范式,通常意味着,你主要使用的是什么样的代码结构。从设计的角度说,编程范式决定了你在设计的时候,可以使用的元素有哪些。
现在主流的编程范式主要有三种:
结构化编程,限制使用 goto 语句,它是对程序控制权的直接转移施加了约束。
面向对象编程,限制使用函数指针,它是对程序控制权的间接转移施加了约束。
函数式编程,限制使用赋值语句,它是对程序中的赋值施加了约束。
这里我主要讲结构化编程里的例子。
PS:以下例子出自软件设计之美里的13 | 结构化编程:为什么做设计时仅有结构化编程是不够的?,而我也结合他讲的东西来说明观点,具体可以点击链接查看。
学过c的同学一定清楚选择结构 if/else,循环结构 do/while吧,但是,你有没有想过,这些结构是怎么来的呢?
我们都知道,今天的编程语言都是高级语言,那对应着就应该有低级语言。就今天这个讨论而言,比高级语言低级的就是汇编语言。如果你去了解汇编指令,你会发现,它的编程模式与我们习惯的高级语言的编程模式有着很大的差异。使用汇编写代码,你面对的是各种寄存器和内存地址。那些我们在高级语言中经常面对的变量,需要我们自己想办法解决,而类型,则统统没有。至于前面提及的那些控制结构,除了顺序结构之外,在汇编层面也是不存在的。
连 if/else 和 do/while 都没有,那我们如何写程序?
别急,在汇编里有个 goto,它可以让代码跳转到另外一个地方继续执行。还有几个比较指令,让你可以比较两个值。
我们先想一下, if 语句做的是什么呢?执行一个表达式,然后,根据这个表达式返回值是真是假,决定执行 if 后面的代码,还是 else 后面的代码。
好,如果我们这么写汇编代码,就是先执行一段代码,把执行结果和 0 比较。如果不等于 0 就接着执行,等于 0 就跳转到另外一个地方执行,这不就和 if 语句的执行逻辑是一样的吗?
而do/while也是类似的做法。
PS:如果是你,你会怎么来设计实现do/while 逻辑?
原来的程序员面对的的确是这些汇编指令,但是他们是站在直接使用指令的角度去思考。所以,他们更习惯按照自己的逻辑去写,这其中最方便的写法当然就是需要用到哪块逻辑,就 goto 到哪里执行一段代码,然后,再 goto 到另外一个地方。
这种写起来自由自在的方式,在维护起来却会遇到极大的挑战,因为你很难预测代码的执行结果。有人可能只是图个方便,就 goto 到一个地方继续执行。可只要代码规模稍微一大,就几乎难以维护了,这便是非结构化的编程方式。
所以结构化编程就是对其作出一个限制,限制你直接使用goto语句,因为这会极大影响代码的质量。而一些现代程序设计语言干脆在设计上就把 goto 语句拿掉了。
所以我们看到,语言是一种更高层次的抽象,现在我们所说的高级语言,并不是说着语言一定很厉害,而是说它抽象的层次比较高。
而语言本身呢,不是让我们能做什么,而是让我们不能做什么。
语言本质上是一种约束。
哈哈,讲了这么多,我现在还是没开始介绍Java。
我讲这些目的是想让大家在学习Java的开始阶段,带给大家一个更宽阔的视野,带领同学们以不同的角度去思考问题,毕竟这个社会不缺搬砖的码农,缺的是能看到问题本质,能去思考,能去解决问题的工程师。
也许上面的内容对于初学者的你有点难度,很多东西都是一知半解,但是这就够了。我上面讲的这些不是让你真正能明白这些,而是让你有个印象,让你们明白学习Java不仅仅是要学习基础的语法,更是一些深层次的东西。也许我今天讲的这些能让你们在未来学习新知识时有个新的理解,给你们带来一定的帮助。
最后我还是想说一点,学习一种思考方式比学习一种技术更为重要,在这个技术快速迭代的时代下,这也是我们的最为宝贵的财富之一。
Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。
优点:
(1)一次编写,处处运行。
(2)系统的多平台支持。
(3)强大的可伸缩性。
(4)多样化和功能强大的开发工具支持。
(5)良好的生态支持
(6)开源且版本持续迭代升级
(7)垃圾回收机制
(8)屏蔽了一些底层的操作(相对于c++而言),使代码不容易出错
缺点:
(1)相较于c这种比较接近机器的语言来说,性能较低(不过相较于其他面向对象的语言来说,性能还是可以的)
(2)对于Python这种语言来说,语法较为复杂,写的代码更多。Python能用较少的代码完成同一件事。(但我觉得Java代码看起来更规范,更舒服,也许是我先入为主的观念导致的错觉)
(3)无法直接操作底层内存(当然这既是优点也是缺点)
现今国内的服务端开发基本是采用Java进行开发的。
就算你以后不打算从事Java相关的工作,这门语言给你带来的绝不仅仅是语言那么简单,更是一种思想。以后你要学习其他面向对象的语言,你会发现你学的会很快。
Java拥有其他语言无法企及的生态
上图是gitee2020的年度报告,这里我们看到Java的占比稳居第一,可见其生态圈的庞大。
如果从就业而言,Java岗位是最多的。
注意这里只是说岗位最多,不代表留给你的岗位多,Java竞争还是蛮激烈的。
JDK:java development kit (java开发工具)
JDK主要包含三部分,
第一部分就是Java运行时环境,JVM。
第二部分就是Java的基础类库,这个类库的数量还是非常可观的。
第三部分就是Java的开发工具,它们都是辅助你更好的使用Java的利器。
jdk版本很多,各个版本之间也有较大差异,但是都遵循向后兼容原则(版本低的项目可以在jdk高的运行环境中运行)。目前为止jdk已经更新到了15,但是长期版本(官方会长期维护的版本)只有两个——8和11,因为各种原因(如技术包裹等),企业里jdk版本大多是8。
所以我建议这里下载8或者11这两个版本。
这里我们以8为例,点击jdk download。
因为我是windows 64位的系统,我就选择windows x64版本,大家选择自己电脑的对应版本即可。
这里我选择了exe,因为他是可执行程序(有引导安装的程序),安装时只需不断下一步即可,简单方便,俗称“傻瓜式安装”
点进去后会有个oracle账号登录(Java是sun公司的,后来被oracle收购了),因为我这里之前注册过了,所以直接登录即可。未注册的按照步骤去注册一下即可。
学过Java的人肯定明白使用Java前要配置环境变量,但你们知道为什么要配置环境变量吗?
我相信绝大部分人不清楚配置环境变量的作用,遇到问题甚至会去想是不是我环境变量配错了。
说实话,在现在这种环境下,一般不配环境变量也没什么关系。
因为我们并不会去命令行里编译运行java文件,我们现在的操作一般都是直接在idea里展开的,而idea里可以指定项目jdk的目录。所以,你在后面可以发现,你下了个新版本的jdk,并没有配置环境变量,可项目依旧能运行(只需指定新下的jdk路径即可)。
回到我们的问题上来,配置环境变量有什么用呢?
在以前,jdk环境变量的配置是必不可少的,因为很多时候我们会打开cmd来编译运行,或者你用第三方工具,比如eclipse,这些时候它会去寻找jdk中的相应exe可执行文件来编译运行,如果没有配置环境变量,那么jdk的路径是找不到的,因为它默认只在环境变量里配置过的路径里寻找。
举个具体的例子,如果我没有配置环境变量,那么当我在cmd中输入java -version时会出现如下情况:
当我们配置了环境变量后,再输入java -version
是不是很神奇啊,其实原理很简单,你输入这个命令是需要相对应的exe文件来运行的,而这些命令在jdk的bin目录下,如果你没有配置环境变量,那么系统就找不到这些可执行文件(因为系统默认会去path配置的路径中找),那么自然无人来执行这些个命令,自然就会报“‘java’不是内部命令”的错误,因为系统默认路径下没有相应文件来执行这个命令的。
所以针对以上原理我们还有一种方法,既然系统找不到目录,那么我们就进到相应目录下去执行命令就好了
但这个方法治标不治本,因为每次执行你都得进到相应目录下,所以配置环境变量是个一劳永逸的方法。
以下步骤是针对用下载zip压缩包安装的步骤
教大家一个在windows10系统中便捷打开的方式,打开开始按钮输入“环境变量配置”,就可以看到
选择用户变量或者系统变量(两者皆可,但不要一个变量配置在用户变量,一个变量配置在系统变量,因为这样两者是互不可见对方的)。
这里我选择在用户变量里配置,
点击新建,
在变量值出输入你解压jdk的路径,至于变量名输入JAVA_HOME(如果认真理解了我讲的配置环境变量作用,那么大家也会明白这里的变量名是可以随便起的,只需做到前后一致即可)
然后找到Path这个变量,点进去
点击新建
输入“%JAVA_HOME%\bin”,然后点击确定就完成了。
其实我们这么做的原理就是配置一个jdk的bin目录路径到变量中,这样系统就可以在任何地方找到Java相应的可执行文件。
PS:这里单独配置JAVA_HOME是为什么?
相信现在一些人在初学Java时,会跟着一些视频或者教程去按部就班地配置环境变量。
可事实上,如果按照exe方式去安装jdk,我们并不需要配置环境变量。(Java也是与时俱进的)
PS:这里你能看到什么问题?你有什么思考?
其实这奥秘就在于它给我们配置了这么两个环境变量:
看到这里,相信大家也就明白了,虽然安装程序并没给我们配置jdk的bin目录地址,但是它把编译执行需要的exe文件拷贝了一份到这个目录,那么我们也就达到了相应的效果。
PS:为什么我讲环境变量配置要讲这么详细,还带领同学们去探究为什么exe安装不用配置环境变量,因为我想让同学们不要仅仅停留在表层,更多的,我想让同学们去学会如何思考,学会多去问问为什么,学会探究问题的能力和思考方式。我觉得这点是才我上这堂课的真正目的。
在没有IDE的年代,记事本其实也是个“不错” 的开发工具。
很难想象,在十几年前的开发是怎样的一个状态。每次写完一个Java文件,便要到cmd中编译运行,一旦出错那就是反复找bug的噩梦,因为很多时候是因为漏打或者错打了某个单词字母而出现的编译不通过。
再回过来想想现在的智能IDE,简直不要太香!
集成开发环境(IDE,Integrated Development Environment )是用于提供程序开发环境的应用程序,一般包括代码编辑器、编译器、调试器和图形用户界面等工具。集成了代码编写功能、分析功能、编译功能、调试功能等一体化的开发软件服务套。所有具备这一特性的软件或者软件套(组)都可以叫集成开发环境。
在Java编写中,最常见的IDE莫属eclipse和idea了,这两者都是非常好用的IDE。
eclipse是一款免费的IDE软件,在早些年的开发中非常流行,其针对不同场景有不同的版本。但是自从idea异军突起,eclipse的出镜率逐年下降。
idea是目前Java界中公认的最好用的IDE,没有之一,无论是代码提示,还是界面设计还是各种插件支持,它做的都比eclipse要好,它是JetBrains公司出品的一系列产品的集大成者。但是可惜的是idea是一款收费软件,一年要千把块钱,当然学生可以使用学生邮箱免费试用。
我个人还是比较推荐使用idea的。一开始我是使用eclipse的,但自从用了idea后,发现越来越离不开idea了。
这里就不多详细介绍了,参见jdk安装,任何有名的软件只要搜一下下载安装很简单的。(idea也是直接下一步就行,不用去管其他的)
输入sout便会直接出来“System.out.println();”
输入main便直接会出来main的主函数。
…
看英文不太习惯的同学按如下操作
安装重启即可。
打开设置点击快捷键即可
列举一下我自己常用快捷键:
1)删除一整行
2)开始新行
3)重复整行
4)将整行代码向下移动
5)后退(debug或者阅读源码必备)
以上是本次实验室寒假集训——Java前置知识学习的全部内容了,由于是第一天上午讲,所以我希望带给大家的不仅是知识上的提升,更是视野上的拓展,思考上的提升,以及解决问题能力的提升。我认为只有学会这些技能,我们才能在这条道路上走的更远。
毕竟我一直相信一个道理——授人以鱼不如授人以渔。
前路漫漫,愿大家不要放弃;奋斗路上,你我共行。
愿与君共勉!
写于2021年1月23日
浙江师范大学软件创新实验室