J2EE导论 | 疑惑篇
J2EE是Java程序员从新手进阶的一个必经之路。要体会所谓的工业级代码,就必须要融入和经历更为复杂的开发、部署环境,需要同更多的模块、组件做信息流交换,比较和使用不同的框架,逐一去琢磨和考察它们的必要性及优缺点。
这样一种进阶,注定了其过程必然是痛苦的。这不仅是因为你要掌控和关注的细节、模块一下子陡然攀升,更因为这些增加的细节和模块背后都蕴含着各种复杂的理论知识:网络、web、程序构建。如果再考虑到你要使用的计算机,从一台PC变成多台服务器的交互,而部署环境从一直使用的eclipse自动化,变成多台Linux的部署,各种不适合不理解一下子都全部爆发,实在是巨大的挑战。
还记得当初最开始学习J2EE的时候,没用到一个月时间,就从入门走向了放弃。太多繁杂的部署和配置文件,理论知识又弄得来似是而非,更为要命的是当初根本没有什么软件工程的思想和意识,就简单粗暴地把这些繁琐工作扣上了一个“苦力”的帽子。并且自我安慰道:这么多复杂的零碎,不就是农民工搬砖么,果然是码农,我才不走这样的路。而完全没有意识到,这正是软件工程思想的匮乏所导致的。
正是因为事务性的东西太多,所以你才需要有出色的工程能力,运用你的谋篇布局将复杂的管理任务,通过各种工具、技巧和构架,把它们逐一消磨,从而让所有的细节都在自己的掌控之中,有条不紊地把一项浩繁的工程管理好。
我想,这一思想是一名优秀的软件工程师,也是J2EE入门所必备的 ,那就是控制复杂度是所有工程师最本质的任务。如果出现了细节太过繁杂,让自己深陷其中而无法解脱时,就一定要停下来跳出去思考,自己的整个工作流程应该做怎样的优化和改进,应该如何重构自己的流程和组织,从而把整个团队和工作流程理顺,发挥出他们应有的实力。
也即是,当你面对复杂问题的时候,你不会用消极的放弃或者粗暴的贬低来逃避复杂度失控的现实,而是会更加积极地去寻求改进方案,让自己更有条理更高效地完成任务。
怀揣着这一思想,就可以更为深入地探讨J2EE对新人的挑战和隐藏的深坑。在我看来学习Java,对新手来讲有这么几个坑:
1、不关注Java命令的运行
因为Eclipse的大而全,从而完全不会使用java的命令行,更不知道Java参数是些什么鬼。
或许一般的教科书会谈到一点如何通过命令行去运行Java,但紧接着,后面会补充道,有了Eclipse我们就不需要关注这些繁琐的细节。然后把Java命令行的东西永远地抛到脑后。
话是没错,有了Eclipse,谁还会去关注那堆交互极差的命令行?
可正如我在前面所说,当你运行的机器,从个人PC变成了远程端的Linux Server,你还能不关注命令行吗?甚至,让我问一个更为傻气但往往却能戳中新手痛点的一个问题:你使用的Linux Server端,很可能连图形界面都没有,请问如何使用你熟悉而又引以为傲的Eclipse呢?进一步,Eclipse都没有,请问你如何debug呢?又如何加断点,做你习以为常的单步调试,看着一条条的黄色加亮行debug?
从这个角度讲,你或许就能够理解:为什么单步调试并不总是一个好的方法。同样地,为什么你需要学习不同的调试技术,为什么需要学会怎么写log又如何依靠log来做debug。种种这些说法和论调,都会因为你使用工具、计算机的环境的改变而改变。
为什么你以前无法理解这些东西?
因为你以前只会使用一台PC,不会同远程端的Server打交道。更没有什么严肃的工作和需求,逼迫你同Server打交道。即便是在PC上安装了Linux,你或许也会困惑,为什么要用这堆东西呢?都说Linux好,可为什么自己感觉不到呢?原因就在于,Linux的通常使用环境,并不是作为个人PC来用的。它更多的是被当做Server端的操作系统来使用。你连使用场景都弄错了,那又怎么可能理解和体会Linux的好处?
回到我文章开头的那句话,我说“J2EE是Java程序员从新手进阶的一个必经之路”。那么现在,我能更好地给出这个论断的理由:因为有了J2EE相关项目的介入,你终于可以在一个真实需求的情境下,开始逐一发现你使用计算机的不同情况,进而真正去体会不同的论断和说法。例如,这个部分我提到的关于Eclipse的那些问题。
所以,所谓的为什么软件工程师需要实操、需要有真实的工作经验,为什么它们有时候比学校的理论来得重要。这就是因为,“工作”本身会为你提供一个真实的需求,而不是学校书本里自己臆想的一个伪需求,来让你一个个地去体会真实世界中的限制,进而再看到那些曾经在书本上但却不以为意的解决方案或工具时,便会有一种大梦初醒的感觉。
2、不知道Java运行的是什么
同样是因为过于依赖大而全的Eclipse,你逐渐会“忘记”,你运行Java的时候,到底在运行什么。或许,你早已在书本上看过,Java源代码需要经过编译变成class字节码,再由JVM把这堆字节码变成所在平台的机器码,进而这堆机械码被加载进内存运行。
可一旦要在Server端部署代码,新手的第一反应很可能就是我上面提到的:我的Eclipse在哪里?没有了Eclipse,我的Java怎么运行?
这其实就是完全没有真正理解上面说的Java运行机制。要运行起来Java,有了JVM、有了class文件就够了啊,你要Eclipse干嘛?
更进一步:OK,就算有class,我不需要通过Eclipse来做编译,可那些jar包的依赖怎么玩儿?每次的jar的依赖都是靠Eclipse来做的连接,没有了它,依赖关系怎么做?
这就又回到了第一部分提到的,根本不懂如何使用Java的命令行,更加不知道Java参数是些神马鬼。更本质来讲,你并不清楚Eclipse为你封装、简化的服务是些什么。你不了解,在Eclipse的背后,到底调动了那些命令来指挥你程序的运行,而这些调动的东西,如果不通过Eclipse又该通过什么方式被实现?
或许你可以辩解道,我曾经的编程工作确实不需要了解这些底层啊,因为了解了也没用,我还是会用Eclipse来简化我的工作。
所以咯,这就是学习J2EE的价值,强迫你弄懂这些细节,并且真的会在Server端的部署和开发中运用到。你不得不关注这些Java的依赖和build,从而更深入地理解Java的运行方式,进而才可以体会到为什么需要所谓的部署工具,从最简单的makefile,到比较流行的Ant、Maven等。
3、服务器端的Java入口在那儿
这是另一个有点玄乎的问题,但同样是因为长期在Eclipse环境下做开发导致的。要开发、测试你的程序,那么第一步,你至少要让它运行起来。那么,通常的做法是什么呢?
那当然是在Eclipse中点开某个具有main函数的java文件,然后点击Eclipse的运行按钮。
等到了J2EE的环境下,你会惊讶地发现,你竟然不知道如何将自己写的这堆代码给跑起来。一来当然是因为那个老问题,Server端没有Eclipse,我如何点击运行按钮?
再来,就算我知道可以通过Java命令行来开启一个Java程序的运行,可是,随便拿来一套J2EE的源代码,你竟然找不到一个类是有main函数的!
这可一下子就傻眼了,main函数都没有,你让我如何使用Java命令行把整个代码启动起来?
且等后面再回答这个问题,让我们再提一个有着相同理由的另一个问题。
4、数量繁多的配置文件和互补相关的源代码
让J2EE从新手走向放弃的另一大关键,就是“数量繁多的配置文件”和看起来“互不相关的源代码”。随便拿到一个J2EE的项目,就会发现各种xml和独特格式的文件满天飞。而随便找一个java文件读一段,就更加莫名其妙,似乎这个文件就是独立存在的,没有和别的java类的交互,声明自己有哪些变量、提供好自己的setter/getter,然后,就TM没有然后了!或许你以为这只是个特殊的文件,又接连抓过几个java文件来看,发现都是这样的风格。如此种种,当然会把一个newbie逼到抓狂。
你会因为无法把这些配置文件和类文件的功能连起来而抓狂,又同样因为要不断地切入切出各种种类繁多的文件类型而焦躁:搞这么多的文件类型的目的是什么?为什么需要它们、为什么需要这些独立又互不关联的文件?
要理解这个,就必须回到我们最开始说的关于工程师本质目标的思想:控制复杂度。
控制复杂度最基本的技术就是:分而治之,把一个复杂的问题分解为独立的子问题。
这是一个看起来简单,实则深不见底的技术。甚至可以这样夸张地说,所有的工程上控制复杂度的技术,都是对这一条的直接/间接地使用,又或是通过复杂的其它技术的辅助,来实践这一条技术。
将问题分而治之,有很多好处,其重要的就两条:
一是把问题分解后,你就可以不必直接面对一个大问题,从而可以更好地通过各个击破的方式将它解决。用最通俗的话来讲,就是饭要一口一口地吃。你不会直接把一大碗饭倒入嘴里,而是各个击破。
另一个是,当你把问题分解成独立的子问题后,那么复杂度就从系统性的关联复杂性,转变为了一个个小模块各自的复杂度。因为这个独立性,你才得以获得更好的稳定性。因为,就算是一个模块突然出现了问题,由于它的独立性,便可以只把损失限定在它这个模块里,不会影响到系统别的方面。以这样的方式,实实在在地把问题,限定在了一个更小的范围,从而控制住了复杂度。
那么,配置文件、互不相关的源文件、以及Server端的J2EE代码竟然没有main函数,其实都是一系列关于“设计模块、系统构架”的综合技术对这一思想的体现。它们无疑都是为“分而治之”控制复杂度而服务的。
所以,当你有了这些疑问时,其实是最好的学习设计模式和系统构架的机会。因为你有了一个真实场景,从而会立刻能感受到现实的限制条件对你的逼迫。此时,你将会为这些限制而焦头烂额。如果这时候,你去研究一下业界的成熟解决方案,就会很快发现它们都会和设计模式、系统设计搭上线。进而,你便能够势如破竹地理解清楚这些技术的精髓和存在的意义。
5、繁多的理论知识
由于J2EE涉及的环境很多,又是web应用,那么最基本的一点,便是网络、web、Server端的软件、Client端的软件他们之间有什么区别和联系。
还记得我最开始学习J2EE的时候,那简直是胡子眉毛一把抓,且不说把网络和web各种混淆,就连互联网产品和传统IT技术产品的区别都傻傻分不清楚。结果便是,各种概念混用。
而大部分的资料,会一个个地讲解browser的运行方式,讲解HTTP多么高深莫测,又提到Tomcat的Servlet多么本质,又或是Spring框架多么方便和利剑出鞘。可TM从来没有谁把他们串起来,好好地说明他们的职能位置在哪里,在一条生产流水线的位置在哪里。
或许,这是因为这个东西恰好处在一个微妙的尴尬之地:会的人,会觉得这个东西太过简单,拿出讲解或许没啥技术含量,有点不好意思。而不会的人呢,任凭他看多少细节的东西,反正就是不能把各个模块安放在正确的位置,便总是打不通任督二脉,干着急。
我想,我的一个重要任务,便是对这些关联性的东西,做一个细致的宏观review,反正我的脸皮比较厚,不怕diss。
理清楚了这些潜藏在newbie内心模糊的疑问,我们才能在下一篇开始比较系统的自顶向下的技术细节讨论。
不要小看这些问题的梳理。往往,一个newbie从入门走向放弃,就是因为感觉极端模糊,感觉到处都是问题,进而开始展开联想,怀疑是不是自己有问题。而如果能够理清楚自己的问题真正在哪里,就如同分而治之的思想那样,你便能够做到心中有数,只需要把不清晰的技术点,逐一攻破就好了,没什么天塌下来的大事情。
近期回顾
《前端技术的碎碎念》
《放眼望去都是痛》
《网络概念与快递物流》
如果你喜欢我的文章或分享,请长按下面的二维码关注我的微信公众号,谢谢!

更多信息交流和观点分享,可加入知识星球:

VIP赞赏专区:

J2EE导论 | 疑惑篇的更多相关文章
- 【J2EE性能分析篇】JVM参数对J2EE性能优化的影响
一切J2EE应用都是基于JVM的,那么对于JVM的设置和监控,成为J2EE应用程序性能分析和性能优化的必然手段.今天Sincky和大家交流该话题.这里以Tomcat环境为例,其它WEB服务器如Jbos ...
- SQL Server-简单查询语句,疑惑篇(三)
前言 对于一些原理性文章园中已有大量的文章尤其是关于索引这一块,我也是花费大量时间去学习,对于了解索引原理对于后续理解查询计划和性能调优有很大的帮助,而我们只是一些内容进行概括和总结,这一节我们开始正 ...
- SQL Server-简单查询语句,疑惑篇
前言 对于一些原理性文章园中已有大量的文章尤其是关于索引这一块,我也是花费大量时间去学习,对于了解索引原理对于后续理解查询计划和性能调优有很大的帮助,而我们只是一些内容进行概括和总结,这一节我们开 ...
- 编程语言吐槽之Java与C
包含各种偏见和武断,请谨慎阅读. 为什么在学校学习的C,拿到企业生产中不起作用? 而为什么企业级的程序员,依然对C/C++无法掌控?在算法各方面不够精湛? 根本原因还是应用场景的不同.企业级的开发,主 ...
- 一次艰难debug的反思
已经很久没有遇到如此顽固的bug了,总共耗费了我近1个礼拜的时间.期间的种种冲突,个人崩溃,最终解决方案的形成,到回过头来的反思,实在有太多值得梳理的东西. 从结果上来讲,这是个人js基础极端薄弱的集 ...
- SQL Server-字字珠玑,一纸详文,完全理解SERIALIZABLE最高隔离级别(基础系列收尾篇)
前言 对于上述锁其实是一个老生常谈的话题了,但是我们是否能够很明确的知道在什么情况下会存在上述各种锁类型呢,本节作为SQL Server系列末篇我们 来详细讲解下. Range-Lock 上述关于Ra ...
- 学习bootstrap遇到的问题--001 关于bootstrap中类.disabled不禁用默认行为
自学bootstrap遇到的疑惑篇: 按钮状态--禁用 在Bootstrap框架中,要禁用按钮有两种实现方式: 方法1:在标签中添加disabled属性 方法2:在元素标签中添加类名"dis ...
- TGL站长关于常见问题的回复
问题地址: http://www.thegrouplet.com/thread-112923-1-1.html 问题: 网站配有太多的模板是否影响网站加载速度 月光答复: wp不需要删除其他的模板,不 ...
- Java 性能分析工具
如何利用 JConsole观察分析Java程序的运行,进行排错调优 http://jiajun.iteye.com/blog/810150 如何使用JVisualVM进行性能分析 http://jia ...
随机推荐
- 【scarletthln 关于算法的一点总结】
1. 分解问题的角度: fix 某一维度,尝试另一维度上的所有可能 a. 可能是array的(i, j)pointers, b. 可能是矩形的长与宽, c. 可能是tree的每一个subtree, ...
- Codeforces Round #552 (Div. 3) B题
题目链接:http://codeforces.com/contest/1154/problem/B 题目大意:给出n个数,每个数都可以加上或减去这个一个数D,求对这n个数操作之后当所有数都相等时,D的 ...
- angular使用Md5加密
一.现象 用户登录时需要记住密码的功能,在前端需要对密码进行加密处理,增加安全性 二解决 1.利用npm(如果没有,先自行安装npm)安装ts-md5 npm install ts-md5 --sav ...
- PHPEXCEL读出数据是PHPExcel_RichText类型
今天在做导入EXCEL数据时,而且单元格里的数据类型改成文本类型后,在PHPEXCEL读出来的是PHPExcel_RichText类型的,这类型使getValue()是不管用了,因为这时候getVal ...
- 用DOM方式解析XML
一.用DOM方式解析XML 此例子节点结构如下: 1.获取book节点属性 (1).如果不知道节点的属性,通过 NamedNodeMap attrs = book.getAttributes(); 来 ...
- 原来这就是 UI 设计师的门槛
本文主要分享 UI 设计师入行的一些个人经验指南,希望可以带给新入行业的设计师一点帮助! 写在前面 随着互联网的不断发展,特别是移动互联网的不断成熟,视觉设计师也进行了迭代与细分.衍生出的 UI 设计 ...
- axios封装get方法和post方法
我们常用的ajax请求方法有get.post.put等方法,相信小伙伴都不会陌生.axios对应的也有很多类似的方法,不清楚的可以看下文档.但是为了简化我们的代码,我们还是要对其进行一个简单的封装.下 ...
- Vb6调用C#生成的dll
namespace ClassLibrary1 { [ClassInterface(ClassInterfaceType.AutoDispatch)] //注意这行,这行是关键 pub ...
- 无符号1byte转int
在java基本类型中byte是有正负之分,它的取值范围-128到127,有时候在网络编程里我们只需要正数,于是会约定1byte是无符号的,它的取值范围在255-0.那么我们怎么将无符号的1byte转为 ...
- [入门]在Mac OS X下使用和配置Android Studio
Android Studio可谓是安卓开发的XCode,流畅的速度+顺眼的UI足以秒杀Eclipse.在Mac OS X可以通过如下的途径获得Android Studio 最新版本的Android ...