java程序员的就业指导大全_第1页
java程序员的就业指导大全_第2页
java程序员的就业指导大全_第3页
java程序员的就业指导大全_第4页
java程序员的就业指导大全_第5页
已阅读5页,还剩42页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

java程序员的就业指导(重点)

想要成为合格的Java程序员或工程师到底需要具备哪些专业技能,面试者在

面试之前到底需要准备哪些东西呢?本文陈列的这些内容既可以作为个人简历

中的内容,也可以作为面试的时候跟面试官聊的东西,你可以把这些内容写到

你的简历中,当然更需要的是你在面试的时候向面试官展示这些专业技能。相

信此文对正在寻觅Java程序员(Java工程师)职位的freshman以及希望成

为中高级Java开发者的junior都会有所帮助。

专业技能

1.熟练的使用Java语言进行面向对象程序设计,有良好的编程习惯,熟悉

常用的JavaAPI,包括集合框架、多线程(并发编程)、I/O(NIO)、

Socket.JDBC.XML、反射等。[泛型]

2,熟悉基于JSP和Servlet的JavaWeb开发,对Servlet和JSP的工作

原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页

面,有使用监听器、过滤器等Web组件以及MVC架构模式进行Java

Web项目开发的经验。

3.对Spring的IoC容器和AOP原理有深入了解,熟练的运用Spring框架

管理各种Web组件及其依赖关系,熟练的使用Spring进行事务、日

志、安全性等的管理,有使用SpringMVC作为表示层技术以及使用

Spring提供的持久化支持进行Web项目开发的经睑,熟悉Spring对其

他框架的整合。

4.熟练的使用Hibernate.MyBatis等ORM框架,熟悉Hibernate和

MyBatis的核心API,对Hibernate的关联映射、继承映射、组件映

射、缓存机制、事务管理以及性能调优等有深入的理解。

5.熟练的使用HTML、CSS和JavaScript进行Web前端开发,熟悉

jQuery和Bootstr叩,对Ajax技术在Web项目中的应用有深入理解,

有使用前端MVC框架(AngularJS)和JavaScript模板引擎

(HandleBars)进行项目开发的经验。

6,熟悉常用的关系型数据库产品(MySQL、Oracle),熟练的使用SQL和

PL/SQL进行数据库编程。

7.熟悉面向对象的设计原则,对GoF设计模式和企业应用架构模式有深入的

了解和实际开发的相关经验,熟练的使用UML进行面向对象的分析和设

计,有TDD(测试驱动开发)和DDD(领域驱动设计)的经验。

8.熟悉Apache、NginX、Tomcat、WildFly、Weblogic等Web服务器

和应用服务器的使用,熟悉多种服务器整合、集群和负载均衡的配置。

9.熟练的使用产品原型工具Axure,熟练的使用设计建模工具

PowerDesignerEnterpriseArchitect,熟练的使用Java开发环境

Eclipse和IntelliJ,熟练的使用前端开发环境WebStorm,熟练的使用

软件版本控制工具SVN和Git,熟练的使用项目构建和管理工具Maven

Gradleo

说明:上面罗列的这些东西并不是每一项你都要烂熟于心,根据企业招聘的具

体要求可以做相应的有针对性的准备。我个人觉得前6项应该是最低要求,是

作为一个Java开发者必须要具备的专业技能。

项目经验

项目介绍

本系统是X委托Y开发的用于Z的系统,系统包括A、B、C、D等模

块。系统使用了Java企业级开发的开源框架E以及前端技术F。表示层运用了

G架构,使用H作为视图I作为控制器并实现了REST风格的请求;业务逻辑

层运用了J模式,并通过K实现事务、日志和安全性等功能,通过L实现缓存

服务;持久层使用了M封装CRUD操作,底层使用N实现数据存取。整个项

目采用了P开发模型。

说明:上面的描述中,E通常指Spring(Java企业级开发的一站式选择);F

最有可能是jQuery库及其插件或者是Bootstrap框架,当然如果要构建单页

应用(SPA)最佳的方案是前端MVC框架(如AngularJS)和JavaScript

模板引擎(如HandleBars);G显然是MVC(模型•视图•控制),最有可能

的实现框架是SpringMVC,除此之外还有Struts2、JSF以及Apache为

JSF提供的MyFaces实现,可以使用JSP作为MVC中的V,也可使用模板

引擎(如Freemarker和Velocity)来生成视图,还可以是各种文档或报表

(如Excel和PDF等),而Servlet和自定义的控制器是MVC中的C,当然

SpringMVC中提供了作为前端控制器的DispatcherServlet;J通常是事务

脚本,K应该是AOP(面向切面编程)技术,L目前广泛使用的有

memcached和Redis;M的选择方案很多,最有可能的是Hibernate和

MyBatis,也可以两种技术同时运用,但通常是将增删改交给Hibernate来处

理,而复杂的查询则由MyBatis完成,此外TopLink、jOOQ也是优秀的持

久层解决方案;底层的数据存取传统上是使用关系型数据库,可以是

MySQL.Oracle.SQLServer,DB2等,随着大数据时代的来临,也可以采

用NoSQL(如MongoDB、MemBase,BigTable等)和其他大数据存取

方案(如GFS、HDFS等);项目的开发模型P可以是瀑布模型、快速原型模

型、增量模型、螺旋模型、喷泉模型、RAD模型等。

项目开发流程

1.可行性分析>>>可行性分析报告/项目开发计划书

2.需求分析>>>需求规格说明书

。OOAD(用例图、时序图、活动图)

O界面原型:帮助理解需求、业务层设计时推导事务脚本

3.设计>>>概要设计说明书/详细设计说明书

O抽取业务实体(领域对象):类图、E-R图(概念设计阶段)

o分层架构:确定各层的技术实现方案(具体到使用的框架、数据库服

务器、应用服务器等)。业务层设计:事务脚本模式(事务:用户发

送一次请求就是一个事务;脚本:一个方法或一个函数;事务脚本:

把一次请求封装为一个方法或一个函数;事务脚本模式:一个事务开

始于脚本的打开,终止于脚本的关闭)。业务层涉及的对象有三种类

型:事务脚本类(封装了业务的流程)、数据访问对象(DAO,封装

了持久化操作)、数据传输对象(DTO,封装了失血/贫血领域对

象),三者之间的关系是事务脚本类组合(聚合)数据访问对象,这

二者都依赖了数据传输对象

O正向工程(UML类图生成Java代码)和逆向工程(Java代码生成

UML类图)

O数据库物理设计(ER图转换成表间关系图、建库和建表、使用工具插

入测试数据)

4.编码

5.测试>>>测试报告/缺陷报告

O单元测试:对软件中的最小可测试单元进行检查和验证,在Java中

是对类中的方法进行测试,可以使用JUnit工具来实施。

O集成测试:集成测试也叫组装测试或联合测试。在单元测试的基础

上,将所有模块按照设计要求组装成为子系统进行测试。

O系统测试:将已经确认的软件、硬件、外设、网络等元素结合在一

起,进行信息系统的各种组装测试和确认测试,系统测试是针对整个

产品系统进行的测试,目的是验证系统是否满足了需求规格的定义,

找出与需求规格不符或与之矛盾的地方,从而提出更加完善的方案。

•Ajax框架:jQuery、ExtJS.DWR等。

.UI插件:EasyUI,MiniUi等。

•富文本框:UEditor.CKEditor•等。

面试提问

•项目是为哪个公司开发的?项目的投入是多少?

•有多少人参与了项目开发?整个团队中,测试人员、开发人员、项目经理

比例是多少?

•项目开发了多长时间?项目总的代码量有多少?你的代码量有多少?

•项目采用了怎样的开发模型或开发流程?项目的架构是怎样的?项目的技

术选型是怎样的?

.你在项目中承担了怎样的职责?是否经常开会或加班?项目完成后有哪些

收获或是经验教训?

•项目中最困难的部分是什么?如何解决团队开发时遇到的各种冲突?

说明:对于没有实际项目经验的,可以在前程无忧、智联招聘、拉勾网等网站

上搜索招聘Java程序员的公司,找到他们的官方网站了解他们做的项目,直

看项目的详细介绍,然后尝试完成其中一部分功能,最好请教一下高人看看自

己的设it和代码是否恰当,这样相当于积累了一定的项目经验。

面试题

Java常见的面试款已经总结成《Java面试题集》、《Java面试题全集》

以及《面试编程题拾遗》等文章陆续发布在我的CSDN博客,各大公司的面试

题我会继续整理发布。

其他

常见错误

1.只在计算机上练习

2.不做行为面试题演练

3.不做模拟面试训练

4.试图死记硬背答案

5.不大声说出你的解题思路

6.代码不够严谨

7.不写测试代码

8.轻言放弃

面试时可以反问面试官的问题

1.我注意到你们使用了X技术,请问你们是如何解决Y问题的?

2.为什么你们的产品使用了X技术而不是Y技术?据我所知,X技

术虽然有A、B、(:等好处,但也存在D和E问题,而Y技术可

以解决D和E问题。

3.我对您说的X技术不是太熟悉,但我感觉它是一个不错的解决方

案,您能多讲讲它的工作原理吗?

4.你们团队是如何进行项目规划的?一周会有几次例会?每周的代

码量大概是多少?

5.就X问题我能想到的解决方案目前就只有Y了,请问您会怎么解

决这个问题?

S.A.R.法则

S.A.R法则是指先描述问题的场景,然后解释你采取的行动,最后陈述结

果。

算法题的五种解法

1.举例法:通过举例子发现其中的一般规则。

例子:圆内接三角形是锐角三角形的概率是多少?这是搜狗的一个面试题,可

以在圆上随意画三个点连接成三角形就可以知道答案了。

2.模式匹配法

例子:一个有序数组的元素经过循环移动,元素的顺序变成“345612\怎

样找到数组中最小的那个元素,假设数组中的元素各不相同。这个题目和折半

查找看起来是那么相似,因此可以借鉴折半直找的算法,最小元素显然出现在

"mid>right”的转折点。

3.简化推广法

说明:简化问题规模和数据类型,然后再发现通用的解法。

4.简单构造法

例子:找出“abcde”的所有可能的排列组合。先考虑只有“a”的情况,再考虑

“ab”的情况,以此类推。最终你可能会得到一个递归公式。这种方法往往会演

变成递归法。

5.数据结构头脑风暴法

例子:随机生成一些数字,并找出其中位数。这种问题可以在头脑中将你了解

的数据结构过一遍,看看哪种是最合适的数据结构。上面的题目可以建立两介

堆,一个大根堆和一个小根堆,较小的元素放在大根堆,较大的元素放在小根

堆,如果两个堆不平衡,可以从其中一个堆取出元素放入另一个堆即可。最后

中位数应该是两个堆的根之一。

录用谈判

1.要理直气壮的提出具体的待遇要求

2.开出比预期稍高的价码

3.不要只盯着薪水(很多公司更愿意就薪水之外的条件做

出让步)

4.使用最合适的方法(可以尝试在电话或E-mail中谈判

待遇)

自我评价

1.学习能力(搞IT行业的人需要不断的了解新的技术、工具和方法)

2.团队意识(相比个人英雄主义,IT行业更倡导团队合作)

3.抗压能力(很多IT企业的工作强度相对来说还是比较大的)

应聘时最漂亮的回答

应聘时最漂亮的回答

1、请你自我介绍一下刍己好吗?

回答提示:一般人回答这个问题过于平常,只说姓名、年龄、爰好、工作经

验,这些在简历上都有。其实,企业最希望知道的是求职者能否胜任工作,包

括:最强的技能、最深入研究的知识领域、个性中最积极的部分、做过的最成

功的事,主要的成就等,这些都可以和学习无关,也可以和学习有关,但要突

出积极的个性和做事的能力,说得合情合理企业才会相信。企业很重视一个人

的礼貌,求职者要尊重考官,在回答每个问题之后都说一句〃谢谢〃,企业喜

欢有礼貌的求职者。

2、你觉得你个性上最大的优点是什么?

回答提示:沉着冷静、条理清楚、立场坚定、顽强向上、乐于助人和关心他人、

适应能力和幽默感、乐观和友爰。我在北大青鸟经过一到两年的培训及项目实战,

加上实习工作,使我适合这份工作。

3、说说你最大的缺点?

回答提示:这个问题企业间的概率很大,通常不希望听到直接回答的缺点是什么

等,如果求职者说自己小心眼、爱忌妒人、非常懒、脾气大、工作效率低,企业

肯定不会录用你。绝对不要自作聪明地回答“我最大的缺点是过于追求完美",

有的人以为这样回答会显得自己比较出色,但事实上,他已经岌岌可危了。企业

喜欢求职者从自己的优点说起,中间加一些小缺点,最后再把问题转回到优点上,

突出优点的部分,企业喜欢聪明的求职者。

4、你对薪资的要求?

回答提示:如果你对薪酬的要求太低,那显然贬低自己的能力;如果你对薪酬的

要求太高,那又会显得你分量过重,公司受用不起。一些雇主通常都事先对求聘

的职位定下开支预算,因而他们第一次提出的价钱往往是他们所能给予的最高价

钱,他们问你只不过想证实一下这笔钱是否足以引起你对该工作的兴趣。

•回答样本一:我对工资没有硬性要求,我相信贵公司在处理我的问题上会友

善合理。我注重的是找对工作机会,所以只要条件公平,我则不会计较太多。

•回答样本二:我受过系统的软件编程的训练,不需要进行大量的培训,而且

我本人也对编程特别感兴趣。因此,我希望公司能根据我的情况和市场标准

的水平,给我合理的薪水。

•回答样本三:如果你必须自己说出具体数目,请不要说一个宽泛的范围,那

样你将只能得到最低限度的数字。最好给出一个具体的数字,这样表明你已

经对当今的人才市场作了调查,知道像自己这样学历的雇员有什么样的价值。

5、你对加班的看法?

回答提示:实际上好多公司问这个问题,并不证明一定要加班,只是想测试你是

否愿意为公司奉献。

回答样本:如果工作需要我会义不容辞加班,我或在单身,没有任何家庭负担,

可以全身心的投入工作。但同时我也会提高工作效率,减少不必要的加班。

6、如果通过这次面试我们录用了你,但工作一段时间却发现你根本不适合

这个职位,你怎么办?

回答提示:一段时间发现工作不适合我,有两种情况:①如果你确实热爱这个职

业,那你就要不断学习,虚心向领导和同事学习业务知识和处事经验,了解这个

职业的精神内涵和职业要求,力争减少差距;②你觉得这个职业可有可无,那还

是趁早换个职业,去发现适合你的,你热爱的职业,那样你的发展前途也会大点,

对单位和个人都有好处。

7、谈谈你对跳槽的看法?

回答提示:①正常的"跳槽”能促进人才合理流动,应该支持。②频繁的跳槽对

单位和个人双方都不利,应该反对。

8、工作中难以和同事、上司相处,你该怎么办?

回答提示:①我会服从领导的指挥,配合同事的工作。②我会从自身找原因,仔

细分析是不是自己工作做得不好让领导不满意,同事看不惯。还要看看是不是为

人处世方面做得不好,如果是这样的话我会努力改正。③如果我找不到原因,我

会找机会跟他们沟通,请他们指出我的不足,有问题就及时改正。④作为优秀的

员工,应该时刻以大局为重,即使在一段时间内,领导和同事对我不理解,我也

会做好本职工作,虚心向他们学习,我相信,他们会看见我在努力,总有一天会

对我微笑的。

9、你对于我们公司了解多少?

回答提示:在去公司面试前上网查一下该公司主营业务。如回答:贵公司有意改

变策略,加强与国外大厂的OEM合作,自有品牌的部分则透过海外经销商。

10、最能概括你自己的三个词是什么?

回答提示:我经常用的三个词是:适应能力强,有责任心和做事有始终,结合具

体例子向主考官解释,

11、你的业余爱好是什么?

回答提示找一些富于团体合作精神的这里有一个真实的故事有人被否决掉,

因为他的爱好是深海潜水。主考官说:因为这是一项单人活动,我不敢肯定他能

否适应团体工作。

12、作为被面试者给我打一下分?

回答提示试着列出四个优点和一个非常非常非常小的缺点(可以抱怨一下设施,

没有明确责任人的缺点是不会有人介意的)。

13、你为什么要离开原来的公司?

回笞提示:①回答这个问题时一定要小心,就算在前一个工作受到再大的委屈,

对公司有多少的怨言都千万不要表现出来,尤其要避免对公司本身主管的批评,

避免面试官的负面情绪及印象。建议此时最好的回答方式是将问题归咎在自己身

上,例如觉得工作没有学习发展的空间,自己想在面试工作的相关产业中多加学

习,或是前一份工作与自己的生涯规划不合等等,回答的答案最好是积极正面的。

②我希望能获得一份更好的工作,如果机会来临我会抓住。我觉得目前的工作,

已经达到顶峰,即没有升迁机会。

14、你欣赏哪种性格的人?

回答提示:诚实、不死板而且容易相处的人、有〃实际行动”的人。

15、你通常如何对待别人的批评?

回答提示:①沈默是金,不必说什么,否则情况更糟,不过我会接受建设性的批

评。②我会等大家冷静下来再讨论。

16、怎样对待自己的失败?

回答提示:我们大家生来都不是十全十美的,我相信我有第二个机会改正我的错

误。

17、你为什么愿意到我们公司来工作?

回答提示:对于这个问题,你要格外小心,如果你已经对该单位作了研究,你可

以回答一些详细的原因,像〃公司本身的高技术开发环境很吸引我。〃、"我同

公司出生在同样的时代,我希望能够进入一家与我共同成长的公司。、"你们

公司一直都稳定发展,在近几年来在市场上很有竞争力。〃、"我认为贵公司能

够给我提供一个与众不同的发展道路。"这都显示出你已经做了一些调查,也说

明你对自己的未来有了较为具体的远景规划。

18、对这项工作,你有哪些可预见的困难?

回答提示:①不宜直接说出具体的困难,否则可能令对方怀疑应聘者不行。②可

以尝试迂回战术,说出应聘者对困难所持有的态度——工作中出现一些困难是

正常的,也是难免的,但是只要有坚忍不拔的毅力、良好的合作精神以及事前周

密而充分的准备,任何困难都是可以克服。

19、如果录用了你,你将怎样开展工作?

回答提示:①如果应聘者对于应聘的职位缺乏足够的了解,最好不要直接说出

自己开展工作的具体办法。②可以尝试采用迂回战术来回答,如"首先听取领导

的指示和要求,然后就有关情况进行了解和熟悉,接下来制定一份近期的工作计

划并报领导批准,最后根据计划开展工作。。

分析:这个问题的主要目的也是了解应聘者的工作能力和计划性、条理性,而且

重点想要知道细节。如果向思路中所讲的迂回战术,面试官会认为回避问题,如

果引导了几次仍然是回避的话,此人绝对不会录用了。

20、你希望与什么样的上级共事?

回答提示:①通过应聘者对上级的"希望〃可以判断出应聘者对自我要求的意识,

这既上一个陷阱,又是一次机会。②最好回避对上级具体的希望,多谈对自己的

要求。③如"做为刚步入社会的新人,我应该多要求自己尽快熟悉环境、适应环

境,而不应该对环境提出什么要求,只要能发挥我的专长就可以了。

分析:这个问题比较好的回答是,希望我的上级能够在工作中对我多指导,对我

工作中的错误能够立即指出。总之,从上级指导这个方面谈,不会有大的维漏。

21、与上级意见不一时,你将怎么办?

回答提示:①一般可以这样回答“我会给上级以必要的解释和提醒,在这种情况

下,我会服从上级的意见。"②如果面试你的是总经理,而你所应聘的职位另有

一位经理,且这位经理当时不在场,可以这样回答:"对于非原则性问题,我会

服从上级的意见,对于涉及公司利益的重大问题,我希望能向更高层领导反映。〃

分析:这个问题的标准答案是思路①,如果用②的回答,必死无疑。你没有摸清

楚改公司的内部情况,先想打小报告,这样的人没有人敢要。

22、为什么选择我们公司?

回答提示:曾经在报章杂志看过关于贵公司的报道,与自己所追求的理念有志一

同。而贵公司在业界的成绩也是有目共睹的,而且对员工的教育训练、升迁等也

都很有制度。

分析:去面试前先做功课,了解一下该公司的背景,让对方觉得你真的很有心想

得到这份工作,而不只是探探路。

23、谈谈如何适应办公室工作的新环境?

回笞提示①办公室里每个人有各自的岗位与职责,不得擅离岗位。②根据领导指

示和工作安排,制定工作计划,提前预备,并按计划完成。③多请示并及时汇报,

遇到不明白的要虚心请教。④抓间隙时间,多学习,努力提高自己的政治素质和

业务水平。

24、除了本公司外,还应聘了哪些公司?

回答提示:很奇怪,这是相当多公司会问的问题।其用意是要概略知道应徵者的

求职志向,所以这并非绝对是负面答案,就算不便说出公司名称,也应回答"销

售同种产品的公司",如果应聘的其他公司是不同业界,容易让人产生无法信任

的感觉。

25、你还有什么问题要问吗?

回答提示:企业的这个问题看上去可有可无,其实很关键,企业不喜欢说"没问

题"的人,因为其很注重员工的个性和创新能力。企业不喜欢求职者问个人福利

之类的问题,如果有人这样问:贵公司对新入公司的员工有没有什么培训项目,

我可以参加吗?或者说贵公司的晋升机制是什么样的?企业将很欢迎,因为体现

出你对学习的热情和对公司的忠诚度以及你的上进心。

26、如果你被录用,何时可以到职?

回答提示:大多数企业会关心就职时间,最好是回答〃如果被录用的话,至I」职日

可按公司规定上班",但如果还未辞去上一个工作、上班时间又太近,似乎有些

强人所难,因为交接至少要一个月的时间,应进一步说明原因,录取公司应该会

通融的。

Java程序员们最常犯的10个错误

Java程序员们最常犯的10个错误

将数组转化为一个列表时,程序员们经常这样做:

List<String>list=Arrays.asList(arr);

Arrays.asList。会返回一个ArrayList对象,ArrayList类是Arrays的一个私有

静态类,而不是java.util.ArrayList类,java.util.Arrays.ArrayList类有set。、

get()、contains。方法,但是没有增加元素的方法,所以它的大小是固定的,

想要创建一个真正的ArrayList类,你应该这样做:

ArrayList<String>arrayList=newArrayList<String>(Arrays.asList(arr));

ArrayList的构造方法可以接受一个集合类型,刚好它也是

java.util.Arrays.ArrayList的超类。

2.判断一个数组是否包含一个值

程序员们经常这样做:

Set<String>set=newHashSet<String>(Arrays.asList(arr));

returnset.contains(targetValue);

这段代码起作用,但是没有必要把一个数组转化成列表,转化为列表需要额外

的时间。它可以像下面那样简单:

Arrays.asList(arr).contains(targetValue);

或者是:

for(Strings:arr)(

if(s.equals(targetValue)){

returntrue;

)

)

returnfalse;

第一种方法比第二种更容易读

3.在一个循环中删除一个列表中的元素

思考下面这一段在循环中删除多个元素的的代码

ArrayList<String>list=new

',

ArrayList<String>(Arrays.asList("a"/"b/c"/"d"));

for(inti=O;i<list.size();i++){

list.remove(i);

)

System.out.println(list);

输出结果是:

[b,d]

在这个方法中有一个严重的错误。当一个元素被删除时,列表的大小缩小并且

下标变化,所以当你想要在一个循环中用下标删除多个元素的时候,它并不会

正常的生效。

你也许知道在循环中正确的删除多个元素的方法是使用迭代,并且你知道java

中的foreach循环看起来像一个迭代器,但实际上并不是。考虑一下下面的代

码:

ArrayList<String>list=new

n,,nn

ArrayList<String>(Arrays.asList(a",b/c"/"d"));

for(Strings:list){

if(s.equals(na")){

list.remove(s);

)

)

它会抛出一个ConcurrentModificationException异常。

相反下面的显示正常:

ArrayList<String>list=new

n',B

ArrayUst<String>(Arrays.asList("a/"b","c/"d));

Iterator<String>iter=list.iteratorQ;

while(iter.hasNext()){

Strings=iter.next();

if(s.equals(na")){

iter.remove();

)

)

.next。必须在.remove。之前调用。在一^foreach循环中,编译器会使.next。

在删除元素之后被调用,因此就会抛出ConcurrentModificationException异

常,你也许希望看一下ArrayList.iterator()的源代码。

4.Hashtable与HashMap的对比

就算法而言,哈希表是数据结构的一个名字。但是在java中,这个数据结构的

名字是与的一个重要不同点是

HashMapoHashtableHashMapHashtable

是同步的。所以你经常不需要Hashtable,相反HashM叩经常会用到。

5.在集合中使用原始类型

在Java中原始类型与无界通配符类型很容易混合在一起,拿Set来说,Set是

一个原始类型,而Set<?>是无界的通配符类型。

考虑下面使用原始类型List作为参数的代码:

publicstaticvoidadd(Listlist,Objecto){

list.add(o);

)

pulbicstaticvoidmain(String[]args){

List<String>list=newArrayList<String>();

add(list,10);

Strings=list.get(O);

这段代码会抛出一个异常:

Exceptioninthread"main"java.lang.ClassCastException:

java.Iang.Integercannotbecasttojava.Iang.String

at...

使用原生类型集合是危险的,这是因为原生类型集合跳i寸了泛型类型椅杳,并

且不是安全的,在Set、Set<?>和Set<Object>中有很大的不同。

6.访问级别

程序员们经常使用public作为类字段的修饰符,可以很简单的通过引用得到

值,但这是一个坏的设计,按照经验,分配给成员变量的访问级别应该尽可能

的低。

7.ArrayList与LinkedList的对比

当程序员们不知道ArrayList与LinkedList的区别时,他们经常使用

ArrayList,因为它看起来比较熟悉。然而,它们之前有巨大的性能差别。简而

言之,如果有大量的增加删除操作并且没有很多的随机访问元素的操作,应该

首先

LinkedListo

8.可变与不可变

不可变对象有许多的优点,比如简单,安全等等。但是对于每一个不同的值都

需要一个独立的对象,太多的对象可能会造成大量的垃圾回收。当选择可变与

不可变时应该有一个平衡。

一般的,可变对象用来避免产生大量的中间对象c一个典型的例子是连接大量

的字符串。如果你用一个不可变的字符串,你会产生很多需要进行垃圾回收的

对象。这很浪费CPU的时间,使用可变对象是正确的解决方案(比如

StringBuilder)o

Stringresult="";

for(Strings:arr){

result=result+s;

)

有时在某些情况下也是需要可变对象的,比如将可变对象作为参数传入方法,

你不用使用很多语句便可以得到多个结果。另外一个例子是排序和过滤:当

然,你可以写一个方法来接收原始的集合,并且返回一个排好序的集合,但是

那样对于大的集合就太浪费了。

9.父类与子类的构造函数

classSuper{

Strings;

publicSuper(Strings){

this.s=s;

)

)

publicclassSubextendsSuper{

intx=200;

publicSub(Strings){

)

publicSubQ{

System.oyt.println("Sub");

)

publicstaticvoidmain(String[]args){

Subs=newSub();

)

)1

这个编译期错误的出现是父类默认的构造方法未定义,在java中,如果一个类

没有定义构造方法,编译器会默认的为这个类添加一个无参的构造方法。如果

在父类中定义了构造方法,在这个例子中是Super(St「ings),编译器就不会添加

默认的无参构造方法,这就是上面这个父类的情形。

子类的构造器,不管是无参还有有参,都会调用父类的无参构造器。囚为编译

器试图在子类的两个构造方法中添加super。方法。但是父类默认的构造方法未

定义,编译器就会报出这个错误信息。

想要修复这个问题,可以简单的通过1)在父类中添加一个Super。构造方法,

像下面这样:

publicSuper(){

System.outprintln("Super");

)

或者2)移除父类自定义的构造方法,或者3)在子类的构造方法中调用父类的

super(value)方法。

10.〃”还是构造器

有两种方式可以创建字符串

〃1.使用字符串

Stringx=nabc";

〃2.使用构造器

Stringy=newString("abc");

有什么区别?

下面的例子会给出一个快速的答案:

Stringa=nabc';

Stringb="abc";

System.out.println(a==b);//true

System.out.println(a.equals(b));//true

Stringc=newString("abcw);

Stringd=newString("abcn);

System.out.println(c==d);//false

System.out.println(c.equals(d));//true

java代码效率优化

JAVA代码效率优化

最近在想自己编程时是否注意过代码的效率问题,得出的答案是:没有。代码

只是实现了功能,至于效率高不高没怎么关注,这应该是JAVA程序员进阶的

时候需要考虑的问题,不再是单纯的实现功能,也不是完全依赖GC而不关注

内存中发生了什么,而要考虑到代码的性能。下面是网上找的一篇关于JAVA

代码优化的文章,觉得不错,就转载了。这里面设计到了JAVA基础和J2EE方

面的优化建议。

L尽量指定类的final修饰符带有final修饰符的类是不可派生的。

如果指定一个类为final,则该类所有的方法都是final。Java编译器会寻找机

会内联(inline)所有的final方法(这和具体的编译器实现有关)。此举能够

使性能平均提高50%°

2、尽量重用对象。

特别是String对象的使用中,出现字符串连接情况时应用StringBuffer

代替。由于系统不仅要花时间生成对象,以后可能还需花时间对这些对象遂行

垃圾回收和处理。因此,生成过多的对象将会给程序的性能带来很大的影响。

3、尽量使用局部变量,调用方法时传递的参数以及在调用中创建的临时变量

都保存在栈(Stack)中,速度较快。

其他变量,如静态变量、实例变量等,都在堆(Heap)中创建,速度较

慢。另外,依赖于具体的编译器/JVM,局部变量还可能得到进一步优化。

4、不要重复初始化变量

默认情况下,调用类的构造函数时,Java会把变量初始化成确定的值:

所有的对象被设置成整数变量(、设置成

null,byteshort.intxlong)0,

float和double变量设置成0.0,逻辑值设置成false。当一个类从另一个类派

生时,这一点尤其应该注意,因为用new关键词创建一个对象时,构造函数链

中的所有构造函数都会被自动调用。

5、在JAVA+ORACLE的应用系统开发中,java中内嵌的SQL语句尽量使

用大写的形式,以减轻ORACLE解析器的解析负担。

6、I/O操作中需要及时释放资源

Java编程过程中,进行数据库连接、I/O流操作时务必小心,在使用完毕

后,即使关闭以释放资源。

因为对这些大对象的操作会造成系统大的开销,稍有不慎,会导致严重的后

果。

7、保证过期对象的及时回收

由于JVM的有其自身的GC机制,不需要程序开发者的过多考虑,从一定程度

上减轻了开发者负担,但同时也遗漏了隐患,过分的创建对象会消耗系统的大

量内存,严重时会导致内存泄露,因此,保证过期对象的及时回收具有重要意

义。

JVM回收垃圾的条件是:对象不在被引用;然而,JVM的GC并非十分的机

智,即使对象满足了垃圾回收的条件也不一定会被立即回收。所以,建议我们

在对象使用完毕,应手动置成null。

8、在使用同步机制时,应尽量使用方法同步代替代码块同步。

9、尽量减少对变量的重复计算

10、尽量采用lazyloading的策略,即在需要的时候才开始创建。

11、慎用异常

异常对性能不利。抛出异常首先要创建一个新的对象。Throwable接口

的构造函数调用名为fiHInStackTrace()的本地(Native)方法,

filllnStackTrace。方法检查堆栈,收集调用跟踪信息。只要有异常被抛出,VM

就必须调整调用堆栈,因为在处理过程中创建了一个新的对象。异常只能用于

错误处理,不应该用来控制程序流程。

12、不要在循环中使用:Try{}catch(){)应把其放置在最外层。

13、StringBuffer的使用:

StringBuffer表示了可变的、可写的字符串。

有三个构造方法:

StringBuffer();〃默认分配16个字符的空间

StringBuffer(intsize);〃分配size个字符的空间

StringBuffer(Stringstr);〃分配16个字符+str」ength()个字符空间

你可以通过StringBuffer的构造函数来设定它的初始化容量,这样可以明显地

提升性能。

这里提到的构造函数是StringBuffer(intlength),length参数表示当前的

StringBuffer能保持的字符数量。你也可以使用ensureCapacity(int

minimumcapacity)方法在StringBuffer对象创建之后设置它的容量。首先我

们看看StringBuffer的缺省行为,然后再找出一条更好的提升性能的途径。

StringBuffer在内部维护一个字符数组,当你使用缺省的构造函数来创建

StringBuffer对象的时候,因为没有设置初始化字符长度,StringBuffer的容

量被初始化为16个字符,也就是说缺省容量就是16个字符。当StringBuffer

达到最大容量的时候,它会将自身容量增加到当前的2倍再加2,也就是(2*

旧值+2)。如果你使用缺省值,初始化之后接着往里面追加字符,在你追加到

第16个字符的时候它会将容量增加到34(2*16+2),当追加至!J34个字符的

时候就会将容量增加到70(2*34+2)。无论何事只要StringBuffer到达它的

最大容量它就不得不创建一个新的字符数组然后重新将旧字符和新字符都拷贝

一遍一这也太昂贵了点。所以总是给StringBuffer设置一个合理的初始化容量

值是错不了的,这样会带来立竿见影的性能增益。StringBuffer初始化过程的

调整的作用由此可见一斑。所以,使用一个合适的容量值来初始化

StringBuffer永远都是一个最佳的建议。

、合理的使用

14Javajava.util.Vectoro

简单地说,一个Vector就是一个java.lang.Object实例的数组。Vector

与数组相似,它的元素可以通过整数形式的索引访问。但是,Vector类型的对

象在创建之后,对象的大小能够根据元素的增加或者删除而扩展、缩小。请考

虑下面这个向Vector•加入元素的例子:

Objectbj=newObject();

Vectorv=newVector(lOOOOO);

for(int1=0;

I<100000;I++){v.add(0,obj);}

除非有绝对充足的理由要求每次都把新元素灌入到Vector的前面,否则

上面的代码对性能不利。在默认构造函数中,Vector的初始存储能力是10个

元素,如果新元素加入时存储能力不足,则以后存储能力每次加倍。Vector类

就对象StringBuffer类一样,每次扩展存储能力时,所有现有的元素都要复制

到新的存储空间之中。下面的代码片段要比前面的例子快几个数量级:

Objectbj=newObject();

Vectorv=newVector(100000);

for(int1=0;I<100000;1++){v.add(obj);}

同样的规则也适用于Vector类的remove。方法。由于Vector中各个元

素之间不能含有“空隙",删除除最后一个元素之外的任意其他元素都导致被

删除元素之后的元素向前移动。也就是说,从Vector删除最后一个元素要比

删除第一个元素"开销"低好几倍。

假设要从前面的Vector删除所有元素,我们可以使用这种代码:

for(int1=0;1<100000;1++)

v.remove(O);

)

但是,与下面的代码相比,前面的代码要慢几个数量级:

for(int1=0;1<100000;!++)

{

v.remove(v.size()-l);

)

从Vector类型的对象v删除所有元素的最好方法是:

v.removeAl旧ements();

假设Vector类型的对象v包含字符串"Hello"。考虑下面的代码,它要

从这个Vector中删除"Hell。"字符串:

Strings="Hello";

inti=v.indexOf(s);

if(I!=-1)v,remove(s);

这些代码看起来没什么错误,但它同样对性能不利。在这段代码中,

indexOf()方法对v进行顺序搜索寻找字符串"Hello".remove⑸方法也要

进行同样的顺序搜索。改进之后的版本是:

Strings="Hello";

inti=v.indexOf(s);

if(I!=-1)v,remove(i);

这个版本中我们直接在remove。方法中给出待删除元素的精确索引位置,

从而避免了第二次搜索。一个更好的版本是:

Strings="Hell。”;v.remove(s);

最后,我们再来看一个有关Vector类的代码片段:

for(int1=0;I++;I<v.length)

如果v包含100,000个元素,这个代码片段将调用v.size()方法100,000

次。虽然size方法是一个简单的方法,但它仍旧需要一次方法调用的开销,至

少JVM需要为它配置以及清除堆栈环境。在这里,for循环内部的代码不会以

任何方式修改Vector类型对象v的大小,因此上面的代码最好改写成下面这

种形式:

intsize=v.size();for(int1=0;I++;I<size)

虽然这是一个简单的改动,但它仍旧赢得了性能。毕竟,每一个CPU周期

都是宝贵的。

15、当复制大量数据时,使用System.arraycopy。命令。

16、代码重构:熠强代码的可读性。

17、不用new关键词创建类的实例

用new关键词创建类的实例时,构造函数链中的所有构造函数都会被自动

调用。但如果一个对象实现了Cloneable接口,我们可以调用它的clone。方

法。clone。方法不会调用任何类构造函数。

在使用设计模式(DesignPattern)的场合,如果用Factory模式创建对象,

则改用clone。方法创建新的对象实例非常简单。例如,下面是Factory模式的

一个典型实现:

publicstaticCreditgetNewCredit(){

returnnewCredit();

)

改进后的代码使用clone。方法,如下所示:

privatestaticCreditBaseCredit=newCredit();

publicstaticCreditgetNewCredit(){

return(Credit)BaseCredit.clone();

)

上面的思路对于数组处理同样很有用。

18、乘法和除法,用移位操作替代乘法操作可以极大地提高性能。

19、在JSP页面中关闭无用的会话。

一个常见的误解是以为session在有客户端访问时就被创建,然而事实是直到

某server端程序调用HttpServletRequest.getSession(true)这样的语句时才

被创建,注意如果JSP没有显示的使用<%@pagesession=wfalse"%>关

闭session,则JSP文件在编译成Servlet时将会自动加上这样一条语句

HttpSessionsession=HttpServletRequest.getSession(true);这也是JSP中

隐含的session对象的来历。由于session会消耗内存资源,因此,如果不打

算使用session,应该在所有的JSP中关闭它。

对于那些无需跟踪会话状态的页面,关闭自动创建的会话可以节省一些资源。

使用如下page指令:<%@pagesession="false"%>

20、JDBC与I/O

如果应用程序需要访问一个规模很大的数据集,则应当考虑使用块提取方式。

默认情况下JDBC每次提取32行数据。举例来说,假设我们要遍历一个

5000行的记录集,JDBC必须调用数据库157次才能提取到全部数据。如果把

块大小改成512,则调用数据库的次数将减少到10次。

21、Servlet与内存使用

许多开发者随意地把大量信息保存到用户会话之中。一些时候,保存在会话中

的对象没有及时地被垃圾回收机制回收。从性能上看,典型的症状是用户感到

系统周期性地变慢,却又不能把原因归于任何一个具体的组件。如果监视JVM

的堆空间,它的表现是内存占用不正常地大起大落。

解决这类内存问题主要有二种办法。第一种办法是,在所有作用范围为会话的

Bean中实现HttpSessionBindingListener这样,只要实现

valueUnbound。方法,就可以显式地释放Bean使用的资源。

另外一种办法就是尽快地把会话作废。大多数应用服务器都有设置会话作废间

隔时间的选项。另外,也可以用编程的方式调用会话的

setMaxInactivelnterval。方法,该方法用来设定在作废会话之前,Servlet容

器允许的客户请求的最大间隔时间,以秒计。

22、使用缓冲标记

一些应用服务器加入了面向JSP的缓冲标记功能。例如,BEA的WebLogic

Server从6.0版本开始支持这个功能,OpenSymphony工程也同样支持这个

功能。JSP缓冲标记既能够缓冲页面片断,也能够缓冲整个页面。当JSP页面

执行时,如果目标片断已经在缓冲之中,则生成该片断的代码就不用再执行。

页面级缓冲捕获对指定URL的请求,并缓冲整个结果页面。对于购物篮、目录

以及门户网站的主页来说,这个功能极其有用。对于这类应用,页面级缓冲能

够保存页面执行的结果,供后继请求使用。

23、选择合适的引用机制

在典型的JSP应用系统中,页头、页脚部分往往被抽取出来,然后根据需要引

入页头、页脚。当前,在JSP页面中引入外部资源的方法主要有两种:

include指令,以及include动作。

指令:例如<%@该指令在编

includeincludefile="copyright.html"%>o

译时引入指定的资源。在编译之前,带有include指令的页面和指定的资源被

合并成一个文件。被引用的外部资源在编译时就确定,比运行时才确定资源更

晨।效。

动作:例如/,该动作弓入

include<jsp:includepage="copyright.jsp/>oI

指定页面执行后生成的结果。由于它在运行时完成,因此对输出结果的控制更

加灵活。但时,只有当被引用的内容频繁地改变时,或者在对主页面的请求没

有出现之前,被引用的页面无法确定时,使用include动作才合算。

24、及时清除不再需要的会话

为了清除不再活动的会话,许多应用服务器都有默认的会话超时时间,一般为

30分钟。当应用服务器需要保存更多会话时,如果内存容量不足,操作系统会

把部分内存数据转移到磁盘,应用服务器也可能根据"最近最频繁使用"

(MostRecentlyUsed)算法把部分不活跃的会话转储到磁盘,甚至可能抛出

”内存不足〃异常。在大规模系统中,串行化会话的代价是很昂贵的。当会话

不再需要时,应当及时调用HttpSession.invalidate。方法清除会话。

HttpSession.invalidate()方法通常可以在应用的退出页面调用。

、不要将数组声明为

25:publicstaticfinalo

26、HashMap的遍历效率讨论

经常遇到对HashM叩中的key和value值对的遍历操作,有如下两种方法:

Map<String,String[]>paraMap=newHashMap<String,String[]>();

〃第一个循环

Set<String>appFieldDeflds=paraMap.keySet();

for(StringappFieldDefld:appFieldDeflds){

String[]values=paraMap.get(appFieldDefld);

)

〃第二个循环

for(Entry<String,String[]>entry:paraMap.entrySet()){

StringappFieldDefld=entry.getKeyO;

String[]values=entry.getValueQ;

)

第一种实现明显的效率不如第二种实现。

分析如下Set<String>appFieldDeflds=paraMap.keySet();是先从

HashMap中取得keySet

代码如下:

publicSet<K>keySet(){

Set<K>ks=keySet;

return(ks!=null?ks:(keySet=newKeySetQ));

)

privateclassKeySetextendsAbstractSet<K>{

publicIterator<K>iterator(){

returnnewKeyIterator();

)

publicintsize(){

returnsize;

)

publicbooleancontains(Objecto){

returncontainsKey(o);

)

publicbooleanremove(Objecto){

returnHashMap.this.removeEntryForKey(o)!=null;

)

publicvoidclear(){

HashMap.this.clear();

)

)

其实就是返回一个私有类KeySet,它是从AbstractSet继承而来,实现了Set

接口。

再来看看for/in循环的语法

for(declaratior):expression)

statement

在执行阶段被翻译成如下各式

for(Iterator<E>#i=(expression).iterator();#i.hashNext();){

declaration=#i.ncxt();

statement

)

因此在第一个for语句for(StringappFieldDefld:appFieldDeflds)中调用了

HashMap.keySetQ.iteratorQ

而这个方法调用了newKeyIterator()

Iterator<K>newKeyIterator(){

returnnewKeylterator();

)

privateclassKeyiteratorextendsHashIterator<K>{

publicKnext(){

returnnextEntry().getKey();

)

)

所以在for中还是调用了

在第二个循环for(Entry<String,String[]>entry:paraMap.entrySet。)中使

用的Iterator是如下的一个内部类

privateclassEntryiteratorextendsHashIterator<Map.Entry<K,V>>{

publicMap.Entry<K,V>next(){

returnnextEntryO;

)

)

此时第一个循环得到key,第二个循环得到HashMap的Entry效率就是从循

环里面体现出来的第二个循环此致可以直接取key和value值而第一个循环还

是得再利用HashMap的get(Objectkey)来取value值现在看看HashMap

的get(Objectkey)方法

publicVget(Objectkey){

Objectk=maskNull(key);

inthash=hash(k);

inti=indexFor(hash,table.length);//Entry[]table

Entry<K,V>e=table;

while(true){

if(e==null)

returnnull;

if(e.hash==hash&&

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论