1. 中国的程序员数量是否已经饱和
中国的程序员数量没有饱和,程序员属于技术人才,并且程序员需要掌握多种语言去编写,这种人才是很少的,高端智能行业的崛起,对程序员的需求也会增加,所以程序员的数量是没有饱和的。
2. 程序员的困境
近日笔者采访了几十位求职内核程序员这个岗位的候选人。这些候选人均来自大的优秀公司——公司多以芯片或嵌入式OS
/系统而闻名。他们中的许多人都声称自己拥有至少10年的内核在职经验。他们的简历非常耀眼——各种相关的项目,流行语和奖项
但大多数人却无法回答一个很基本的问题:当我们调用标准malloc函数时,内核会发生什么?
不要惊讶。当我要求其中一位候选人基于glib哈希函数编写一个简单的LRU缓存框架时,他一开始表示他从未使用过glib——这也在我意料之中——我给他展示了glib的哈希API页面,并详细解释了API,然后在将近一个小时之后,他只写出了几行乱七八糟的程式码。
我不知道其他国家的情况是否类似,但在中国,或者更具体地说,是在北京,这是现实。那些曾为大型着名外企工作多年的“高级”程序员往往在简单、基本的问题上束手无策。
为什么会出现这种情况?
我越是思考这个问题,就越是觉得问题的原因不仅仅在于他们本身,也在于他们工作的公司。这些公司通常会提供稳定的代码堆栈,而且多年以来一直没有产生显着的变化。围绕代码的技术封闭了程序员的技能,使得他们只需要遵循现有路径,而不必积极创新。如果你在这种代码上工作了很长一段时间,同时没有很好地与时俱进,那么总有一天你会发现自己进退两难——在团队或公司内部,他们叫你“专家”,但却无法在市场上找到同样棒的工作。
这就是所谓的“专家陷阱”。日复一日,程序员梦想着成为团队/公司内部的专家——然而,当这一天真正来临的时候,却是我们困住自己的时候。我们对现有代码挖掘得越深,我们陷入的泥潭就越深。我们渐渐失去了从头开始编写完整项目的能力,因为现有的代码是如此之稳定(如此之大,如此之有利可图)。更糟糕的是,如果我们的主要工作就是维护现有代码,那么一段时间之后,无论我们阅读和学习了多少代码,都会发现,自己不会写代码了——即使问题简单到如研究生院的作业。这就是程序员的困境:我们靠编码为生,大陆但培养了我们的大公司往往会破坏我们谋生的能力。
如何摆脱这种困境?
对于个人——
首先,要做自己的个人项目。你需要不断地“滚颂顷提升自己”。如果工作本身不能帮助你提升自我,那么找一些你想在个人时间解决的问题。这样做有助于你学到新的东西。如果你发布个人项目,比如说在github上,那么你就有机会认识那些能在你换工作时拉你一把的人。
不要停留在同一个团队超过两年。强迫自己换岗位,即使是在同一组织,同一公司中,这样你就可以面对新的挑战和新的技术。每隔18个月去参加工作面试。这不是为了跳槽,而是为了让自己知道现在市场需求什么,以及你该如何适应。
对于团队/公司——
给予员工压力和挑战。轮换岗位,让所谓的“专家”有机会扩充他们的技能。开启新项目,用实战来磨练大家。
定期举办黑客马拉松。这将有樱搭助于建立一种拥抱创新和创造的文化。大家会因彼此而受到激励——
“哎呀,那个家伙能用24小时写出这样一个美丽的框架,我得加油了”。
3. 全世界一共有多少程序员
现在谈到中国软件业时,总是与印度软件业相互比较,是基于这两个国家有很多相似性。在80年代中期,中印两国软件业并无太大差别。中国软件业并未将印度软件业放在眼里,此拜中国高速发展之赐,我们戏言曰印度阿三(是就经济而言,亚洲国家,日本第一,中国居二)。但到了现在印度软件业成了全球老二,叫一向自大的美国人也不敢小瞧,盖茨称其为继美国之后的下一个超级软件大国。中国软件业却看起来是王小二过年了,增长率比起国内其他行业尚可自慰,比起其他软件大国则相形见绌。国内67%的市场份额被外国巨头拿走(的确就是拿,没有被狙击)而且是高端市场。企业在技术竞争力上与外国巨头的差距是越来越大了。大部分软件公司都是在进行一般应用开发,为事企业单位开发管理系统。开发工具是别人的,后端数据库是别人的,绝大多数服务支撑软件也是别人的(修路的利润哪能跟提供大型工具的利润比)。要不是中国盗版猖獗,很多小公司光买开发工具就够呛了。不仅仅是技术差距加大,连从业人员的士气都大受影响。以前,开发出了产品虽然盗版猖獗,但大多赞誉有加,现在,有时连盗都不盗国产软件。过去的程序员们也没多富有,但常被不少爱好者追捧,声望甚着,现在,大概只有出校门没几年的“青光“才为自己的程序员身份得意了。干了几年后,再不愿说自己是光干编码的程序员。中国的程序员们尽管并不认为自己的水平比印度同行差,但大都承认了软件业与印度的差距。也没什么人认为中国软件业形势大好,高歌猛进。至于中国软件业为什么会落败于印度,已有不少总结,在此不表。来看一看业界人士们开出的在网上引发大争议的救业良方。
印度软件业这几年的迅猛发展吸引了全球目光。中国软件业业界人士纷纷以玄奘西行的架势前往取经,这是无可非之。业界人士们取经的结论比较具共性的是:中国软件业需要进行职能化分、大量培养软件蓝领、开拓海外市场等。进行职能化分、实施软件工程、加强管理这些没多大的争议。争议集中在软件蓝领这个新玩意上。
在目前关于美国、日本、西欧等其他软件发达地区的报道中鲜见着软件蓝领这一划分和论述(大师和普通程序员当然有别,哪里都一样)。这是个我们从印度带回来的特产。原因是印度人用高中生在编程,再加上那帮家伙软件工程、项目管理搞的很好,居然能按时上下班,几乎跟哪里都不一样。于是就得出一个软件蓝领的概念(是印度人首创,还是我们的新发明,待考)。可是我要提醒的是印度信息技术部部长2000年5月在华盛顿放言印度每年能向世界输送20万信息专业技术人员,美国现有IT人才签证配额的一半被印度人占据,看来输送的可不是一抓一把的高中生。老美还没那么笨。以印度现在的培训体系现状和实力,那帮高中生经过培训是必然的了。他们可是在中学就接受扎实的计算机教育。我们的所谓的科班出身,不也是从高中拉了一拨人进行再教育吗?我们的大学技术教育是不是比他们的培训体系强,这我没法量化比较。我倒知道谭浩强教授在一次计算机教育会议上说他对中国现在的计算机高手大部份是非计算机科班出身感到迷惑不解。非计算机科班出身的高手得大部分自学吧,还有不少超过天天接受计算机教育的。我也还知道印度IIT被称为亚洲的MIT。我也还知道印度的培训系统来中国帮我们培训技术工程师。尽管业界人士对软件蓝领语带不屑,但要真是我们的教育培训比他们好,那倒是我们应以帮助第三世界兄弟的名义去帮他们。怎么掉过来了。那种因为印度很多编程人员没有大学学历,就把人当作是一抓一把的高中生的人是否也太过皮相之见了。尽管他们不会告你行业污蔑,但我建议有关人员在爆炒软件蓝领时先仔细斟酌一下,去考察一下别人受到的计算机教育再说不晚,程序员里没几个人跟你们抢“软件蓝领”这个词的话语权。也许吧,他们的培训系统比我们差,我们的认证培训系统可以让一个文秘专业的MM在一个月内拿MCSE,真是天才辈出!
软件的开发毕竟还是创造性的活动,你得把要处理的事务进行逻辑转换,再变为程序逻辑,编出代码。即便引入软件工程,把事务进行细分,分成更小的功能模块。你也得进行逻辑转换,离不了思考。要是不想让整个程序慢如老牛,还得仔细考虑对全局的影响。软件工程搞得再好也不能让前一个程序员写if,后一个程序员写else,再后一个打个大括号。要真是不需动脑就能写,用能代码自动生成的开发工具就行了,哪用得着一个人。就是不给薪水也得用一台计算机呀,还浪费能源。你要是在业务流程、核心逻辑不变的情况下改来改去,那是叫维护还是叫开发?开发就是这个样子?如果开发真是做个界面,拉两个控件,改改属性就行,那你还是找一个会Photoshop的人吧,效果肯定好。
继续说这个软件蓝领,我们既然学习印度的管理经验,又带回软件蓝领这个词,还要大力走向世界,看来我们的确是“师印长技以制印”了。前文曾有对世界软件业产业类型的描述。美国的模式,我们现在又缺资金、又缺技术积累,也没合理的产业群落,一时还学不了,以后吧。爱尔兰也没法学,搞20多个版本卖给谁?菲律宾软件产业的增长速度都叫我们吃惊。我们就来看一看印度软件产业,印度产业大部份是外包。我们倒还多了一个国内市场作后院,很占优势吧。仔细来看一看!大家认同的说法是,印度人能拿到外包业务的原因是:官方语言为英语,有语种优势,劳动力成本低廉。当然,还有常提的一句话:中国人和印度人都适合编程,无它,从小重视数学尔。怎样超赶呢?语种优势?印度比我们强。品牌优势?也没法比。我们跟他们比聪明?还是等这方面专家来解释吧,先别那么想。那就拼价格吧!我们就打一场价格战吧!家电业都能打,我们怎么就不行。拼价格那得先降成本,软件的成本主要就是程序员的工资。让一个人均GDP847美元、现有程序员16万人、现在每年培养科班技术人员5万多人的国家跟一个人均GDP300多美元的国家、现有程序员40万、现在每年培养近20万技术人员的国家打人才价格战!当然,我们的认证培训机构能用一个月时间将一文秘专业的MM培养成MCSE技术专家,看来胜利在望!再来看一看我们的后院。我们现在有16万名程序员,分布在近6000家软件公司。这么多的软件公司都能活,那恐怕得感谢这几年的信息化热潮。尽管大部分的软件公司都是做行业应用、管理软件的。但一些大型的行业应用软件并不是由本土企业来完成的。Satyam和Multitech拿下了华为、中兴和联通的几个重要订单,而中国航空系统的管理软件也落入印度软件公司的囊中。一通讯公司的网络核心软件也是其印度研究所完成,这也可算中国软件公司。但却不代表中国软件业的真实水平。有人已在冷思信息化的热潮:虽然各个企业之间千差万别,但同一行业的业务流程却有着惊人的相似,行业应用的标准化这恐怕是这类软件的方向。被讥为“做系统缺少资产; 做应用缺少沟通;做信息缺少分类;做工程缺少规范;做管理缺少制度; 做团队缺少组织“的大多数软件公司如不图变,恐怕无力担当这一责任。在印度几头软件大象已经开始涉足中国市场的时候,我们先不要全都忙着打出去吧!我们有什么优势:管理?资金(软件企业的积累)?技术积累?人力成本?
4. 中国有多少个程序员
中国有185万程序员。
程序员是从事程序开发、程序维护的基层工作人员。一般将程序员分为程序设计人员和程序编码人员,但两者的界限并不非常清楚。
2007年火热的SOA和动态语言各占13%和12%。其实这几大块技术分布他们之间都是有一定的联系的,互联网的发展近两年呈爆炸式的增长态势,中国的网民总数已经超过了1.4亿这样一个巨大的数字。
薪资待遇:
从经济学的层面上来看,软件人才也是劳动力商品中的一种,是由价值规律决定的,有需求才会有市场,才会有人愿意为他们支付工资。当前,包括中国在内,全球都在争夺IT人才,当IT人才的社会总需求大于总供给时,不可避免就会出现人才升值的现象。
5. 全国有多少程序员
中正舆情机构研究出品
点赞分享是一种
积极的
生活态度
6. 全球范围之内程序员的数量大概有多少
埃文斯数据公司(Evans Data Corporation) 2019最新的统计数据(原文)显示,2018年全球共有2300万软件开发人员,预计到2019年底这个数字将达到2640万,到2023年达到2770万。
而来自IDC的统计数据显示,2018年全球软件开发人员数量增长到2230万,而2014年只有1850万程序员。
7. 做程序员要学什么专业
当程序员是什么专业?
计算机科学与技术或软件工程, 不喜欢硬件选软件工程。
打算当程序员,上大学学什么专业 40分
楼上就是在扯蛋,自己不行,还劝别人
我现在在深圳当程序员,工作4年了,目前程序员没以前那么吃香,学得人多了嘛
程序员这个职业在不同学校的专业名称也有所不同,但是差不多了多少,计算机科学及应用,或者计算机软件,到学校问一下就知道了,主流高级汇编语言就是一楼老兄说的C++ .NET JAVA这三门了,C++在游戏方面应用的多一些,网站项目基本都是后面2种语言用得多,JAVA的工资要高点,代码量比较大。
做程序员上大学要念什么专业
软件技术专业
数学学的好坏不能直接说明你能不能学好程序员,写程序还是一个逻辑(if语句,循环语句,对变量的操作,等等...)
最好是本科,院校在计算机专业方面有很好的基础设施和条件
不过专科肯定也是有好的 师资方面都差不多的
以我的感觉是如果哪个院校的软件技术专业的学费高,哪个学校就好 ,呵呵
也在网上找找吧
选学校一定要选好,尤其是大学
我再发表一下自己的观点:大学可以上,有条件当然可以上的;不上大学未必就没出路,未必就没好的工作好的事业;现在培训班多了,去培训班学学也不一定比上过牛比大学的差;技术这方面最后还是要靠自己的能力,自己的自学领悟能力,高手就是在自学中发展起来的,呵呵.
说多了,有句话很有意思,是这么说的:是我上了大学,还是大学上了我.
回答完毕,晚安
做程序员要什么学历什么专业才可以?
很多程序员,很多种情况,有大专、大本,有一个是念得法律后来转行做程序员,有一个是技术院校出身,但是有一群朋友,很喜欢电子类的东西,创办过工作室做网站,也在大公司做信息系统开发,后来做项目经理。如果本身专业和电子相关,就直接去找程序员的工作,如果无关,就需要自己找地方学,或者培训机构,或者学校。
想当一名程序员那在大学时候究竟应该学习什么?
最终我决定把想到的东西写下来,希望能对在校的人有点帮助。首先我们得知道这问题的答案是个变量,他依赖于你的目标和天资能力,绝不唯一。当然大学的课程设置往往是唯一的,所以会有点矛盾。这里最关键的东西是目标,大学学习只是达成最终目标高度的一个环节,他应该为最终目标服务。当然大学生很难清楚的知道自己的目标究竟在那里,但要总归要大致知道自己的方向。这个之所以关键是因为,这直接决定你应不应该学习某个东西。我是在做了很多年软件后,才发现软件和软件的差别其实比马和牛的差别还要大。用流行的分类方法比如:前端开发、后端开发、开发,Java开发等会让人迷失焦点,所以我一直觉得Barry W Boehm在《软件成本估算:COOII模型方法》里的分类方法对学习更有帮助。在这个分类方法里软件被分了三层:最底层是基础结构型(平台)软件的开发;中间层次是开发工具、系统集成、中间件;最上层是终端用户编程,也可以理解为一般应用的开发。同时作者还补充了份数据说:在2005年95%的美国程序员是在做终端用户编程。这似乎把话题扯开了,但其实不是,关键要大致定位下自己的方向。因为对于目标是基础结构的程序员和目标是一般应用的程序员,他们要学习的东西差别很大。Donald Knuth的《计算机程序设计艺术》不是没用,但如果你花了2年把他啃了一遍回头专门做应用开发,那它真的用处不大。至少和一个精通具体语言、框架、设计模式、面向对象、UML的人比只是钻研了《计算机程序设计艺术》的人反倒是在劣势,虽然可能后者更花时间。反过来讲则是在算法密集型的工作里,那优劣情形就会掉过来。无疑的什么都精通最好,但人的时间是有限的,而软件相关的知识是无限的,所以把学习聚焦在自己的目标上非常关键。而目标是什么则要根据自己的实际情形来定。假设说你真的感觉自己的能力挺好,就想做基础结构型的东西,去做MapRece,去做操作系统等等,那首先要认识到的是干这个的人很少,竞争很激烈。如果说在2005年美国只有5%的程序员是干这个的,那我估计今天在中国也顶多是这么个比例。个人感觉,大学的计算机课程还真都是往这个方向培养人的,一旦真的走这个方向,那么大学的计算机课程还真用的上。需要好好学习,天天向上。当然只上课也不行,把课上学的东西实践起来也很关键(比如开源项目)。这里麻烦的事情是,干这个的可能只有5%,很多人即使很努力也不一定挤的上去。那么假设说一个人很现实,说:国内排名靠前的几所学校凑凑也就5%了,竞争太激烈,我不选这个目标方向,我还是95%里做做吧,那这个时候我应该学什么?我个人认为主要要学好一些比较硬的,需要大块时间学习的东西,而不要在花里胡哨的东西上多费时间。硬的东西是指:数据结构和基本算法。不管是不是做基础结构性软件,基本的数据结构和算法知识还是要有的。很可能不太会有自己从头写数据结构和算法的机会,但如果复杂度不知道怎么算,链表、红黑树、哈希表的差别都不知道,那就怎么都玄。精通一门编程语言具体是那个可以根据实际情形来选。但这里强调的是语言,不是IDE和框架。可以通俗理解为每个关键字背后的含义要整清楚。这里的陷阱是学一堆语言,但那个都不精。精读一个有点规模的开源项目(至少要超过2万行)要找那种规模不太大,又比较有名的项目,一定要精读,争取每行都懂。累积一定的代码量不算IDE帮助生成的,争取也在2万行之上。面向对象和设计模式这点最好配合着下一点一起做。从头考察一下某个框架考察某个框架的内存机制、线程机制等。整个学习过程中最常见的陷阱是学会操作一堆IDE和框架的使用,但实际上这事儿价值不大......
做程序员难不?要学什么专业
计算机类的
程序员需要学些什么?
要看你喜好了,做什么都是有兴趣才能学好
想学程序 先确定要学什么 c c++ c# java pb vb等等
现在流行就是c#和java c++也可以 不过比较有深度
先学语法 再学程序实例 最后做项目程序员 工资中上等吧 但是很辛苦
如果你认真学习 不到半年你就会学的很好
作为一个程序员需要学多少技能
介绍下我的想法:
大学里学的是计算机专业,所以顺道学了不少计算机系的基础课程,总体来讲学得很不好,直到大四毕业,我才勉强下定决心要以写代码为生(现在想想,可能是当时实在想不出其他出路)。大学4年,很遗憾的事情就是我没有弄清楚该去真正学些什么东西。
毕业后第一份工作,在一家小公司写servlet/jsp,说实话,我写的很烂,当时带我的人对我的工作很不满意,直到有一次,项目经理跟我谈说,你的工作表现你也看到了,差点就被开掉了,不过我觉得还是要在给你机会。。。当时,我真的是自信心崩溃到极致,觉得自己这段时间其实很努力,但为什么还不入门路。。这次经历给了我非常大的影响,之后的不久,我终于明白了怎么去写那些servlet/jsp,于是我努力的写那些代码,不久,我就成了公司新员工里面,做东西最快的人。当时还发了个公司的什么最快进步奖给我。我想第一份工作给我最大的感受是,想要做为一个程序员,你得先明白,程序是个什么东西。
一年多以后,servlet/Jsp实在不想写了,于是换到另外一家公司,做聊天软件的J2ME客户端。其实我当时不懂J2ME,在刚入职的一个月里,啃完CLDC和一些会用到的JSR的英文文档,然后每天去看项目的代码,有任何问题就去问周边的同事。不久,我也慢慢能写一些J2ME的代码了。接着,我加入了新版客户端的项目组,开始做一些UI组建。最开始,我写一个Text组件,就是把文字显示到屏幕上,还要根据屏幕可显示区域的宽度、高度对文字做调整。没几天,我就信心满满的写完了这些代码,原来写客户端代码也不难啊。不过不久,当同事要用我的组件时,问题百出,以至于同事跟经理抱怨说,这么基础的组件应该给有经验的人去写啊。。 这次,虽然我的工作做的很烂,可自信心倒没受多少打击,因为已经工作一年多了嘛,脸皮厚了不少。但是我心里知道,我的工作肯定哪里出了问题,否则我的组件应该能经受住使用者的考验的啊。这份工作中,我学到了不少东西,首先呢,脸皮要厚一点,不会就追着去问,其次,没有想清楚的话,写出来的东西经不住考验的。再次,英文资料好像更准确啊。当然还有一些具体的编程技术。
大概又过了一年多,大家都说J2ME快完蛋了,android已经开始大兴其道,公司里面也有人在做android客户端,可我还在写没有前途的J2ME.恰好,qq群里有人发消息说招人,我脑子一热,扔了份简历过去。于是,一个多月后,我就到了新的公司上班,这家公司是一个做手机的厂商,而我也可以参与android的开发。在这个公司的前3个月,基本啥活没干,除了学习android之外,就是各种培训和等待。大概待到5个月的时候,我实在坐不住了,我去跟经理说,有没有活可以给 *** 。经理说我考虑下,不久便安排给我一个项目,让我去把它维护好了,然后集成到产品里面。可当我拿到代码时,傻眼了,2w多行代码,而且很多地方写的很复杂,看了好几天也没看懂。好吧,不管了,这件事既然是我负责,那怎么都应该挺住。在接下来的快2个月里,我每天都扑在这两万多行代码里,解决里面的bug,理解里面的设计思路、代码风格、编程技巧,使用公司的工具链,从发布、审核到持续集成等等。我了解到了很多我平时不知道的东西,我解决了发现了的所有的bug。可是最终,我并没有把这个项目维护到可以发布的程度,最后一关的AT&T的稳定性测试宣判了我的这个项目的死刑,随后这两万多行代码慢慢的从我的提交列表里面消失掉了。我第一次明白了,竟然还有如此严格的质量测试,也明白了什么叫风险与代价,虽然这些代码,我已经用monkey模拟跑过了5个钟头,但是依然被ATT测试蹂躏2个钟头之后挂掉。......
以后想当个程序员 大学要学什么专业
好多大学毕业生转行学习it程序开发的。如果你现在就有工作目标,以后想从事软件开发,当个程序员的话,那么建议你大学选择专业的时候就选择计算机相关的专业。
当java程序员应该学什么,并且学的顺序是什么
ja范a有三个方向:1 桌面应用程序开发 不过个人认为这个很少
2 j2me也就是手机里一些小程序的开发
3 j2ee 企业级开发 也是最有前途的
下面是本人j2ee学习的路径 是当时老师跟我讲的
第一步:入门 随便找一本简单的详细的书看完
第二部:看thinking in Java这本书讲解深入 有难度 看完的话受益匪浅 如果 觉得thinking in java 太难的话 就看java核心技术 简单一些 一共两卷 买盗版的吧 很便宜 哈哈
下面就是另外的一层境界了
第三步:html css javascript 这些不是java的内容 但一定要了解
第四步:jsp、servlet JavaBean这个没什么可说的 张孝祥的书不错 很全面 这时可以做个小网站什么的 用mvc设计模式 也就是JSP 负责显示界面 相当于MVC中的 V
Servlet 负责历程控制 相当于MVC中的 C
JavaBean 负责功能 相当于MVC中的 M
第五步:学习struts spring hibernate框架 这时也可以做一些小项目了 实践一 下 当然你会发现实际练习中会有很多问题出现 这是提搞的好机会
第六部:ejb 这是一个重量级的东西 慢慢学吧
8. 哈稀表是什么东西,HashCode是什么
哈希表是一些键值对的组合,如
Hashtable hs = new Hashtable();
hs.Add('1',200);
hs.Add('2',300);
hs.Add('3'悄判汪,400);
他的键是不能重冲备复的。
我们通过它的键就可以得到他的值,如启仔像,我们要得到300.
只需hs['2']就可以得到300
9. 2022年中国一共有多少程序员
超过1000万。根据数据统计可知,2022年中国一共有超过1000万的程序员。程序员是从早蠢事程序开发、维护的专枯启业人员。大多将程序员分为程序设没睁如计人员和程序编码人员,但两者的界限并不非常清楚,特别是在中国。
10. 面试中如何回答HashMap的工作原理
用过哪些Map类,都有什么区别,HashMap是线程安全的吗,并发下使用的Map是什么羡闭,他们
内部原理分别是什么,比如存储方式,hashcode,扩容,默认容量等。
JAVA8的ConcurrentHashMap为什么放弃了分段锁,有什么问题吗,如果你来设计,你如何
设计。
有没有有顺序的Map实现类,如果有,他们是怎么保证有序的。
hashmap的实现原理,https://blog.csdn.net/mbshqqb/article/details/79799009
下面是自己的总结:
存储结构:
里面存储的是一个entry数组,每个数组元素中的结构是一个entry链表
Entry是map中的一个静态内部类,其中的变量有:key,value,hashcocd,下一个Entry
什么是hash?
又称散列,将任意长度的输入通过散列算法转换成固定长度的输出,该输出就是散列值。这是一种压缩映射,散列值的空间通常远小于输出的空间。不同的输入有可能会散列出相同的输出,因此不能从散列值来确定唯一的输入值。这也是为什么比较两个对象不能仅仅使用hashcode方法比较的原因。
hash碰撞:
对不同的值进行hash运算生成了相同的散列值。这个是不可避免的,但是我们需要尽量的减少其带来的损失。
(1)设计好的hash算法让其尽可能的分布均匀
hashmap中的hash算法解析
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
让key的hashcode本身与它右移16位异或,是为了让它的高位与低位混合,增加低位的随机性,同时也变相保持了高位的特征
计算元素位置的算法:
int index = hash & (arrays.length-1);
那么这也就明白了为什么HashMap的数组长度是2的整数幂。比如以初始长度为16为例,16-1 = 15,15的二进制数位00000000 00000000 00001111。可以看出一个基数二进制最后一位必然位1,当与一个hash值进行与运算时,最后一位可能是0也可能是1。但偶数与一个hash值进行与运算最后一位必然为0,造成有些位置永远映射不上值。
对于null值的处理
hashmap是接受兄团裂null值的,null值被放在数组的第一个元素当中,取出来的时候怎么处理呢?
hashmap的工作原理?
它的里面有一个Entry数组,在put时我们先根据key值计算出hashcode,进而计算出该元素在数组中的位置,将健值对封装在Map.Entry对象中,然后存储在数组中
若产生hash冲突怎么办?
每个数组元素的位置都是一个链表结构,若计算出来的hashcode相同则将元素追加到该链表当中,这是hashmap的处理方式
在取元素的时候,先计算key值对应的hashcode ,找到元素所在的位置,然后调用key的equals方法去遍历链表,最后找到元素
还有哪些解决hash冲突的方法?
开放寻址法
这种方法也称再散列法,其基本思想是:当关键字key的哈希地址p=H(key)出现冲突时,以p为基础,产生另一个哈希地址p1,如果p1仍然冲突,再以p为基础,产生另一个哈希地址p2,…,直到找出一个不冲突的哈希地址pi ,将相应元素存入其中。
再哈希法
这种方法是同时构造多个不同的哈希函数:
Hi=RH1(key) i=1,2,…,k
当哈希地址Hi=RH1(key)发生冲突时,再计算Hi=RH2(key)……,直到冲突不再产生。这种方法不易产生聚集,但增加了计算时间。
链地址法
这种方法的基本思想是将所有哈希地址为i的元素构成一个称为同义词链的单链表,并将单链表的头指针存在哈希表的第i个单元中,因而查找、插入和删除主要在同义词链中进行。链地址法适用于经常进行插入和删除的情况。
建立公共溢出区
这种或答方法的基本思想是:将哈希表分为基本表和溢出表两部分,凡是和基本表发生冲突的元素,一律填入溢出表。
默认的负载因子0.75
当map的大小超过当前容量的百分之75时会进行自动扩容,会将原来的对象重新放到新的数组中
rehash 的过程是什么样子的?
说白了就是先resize,生成一个新的Entry数组,再transfer将原数组中的值重新计算index放入新的数组中,然后改变阈值为新的长度x负载因子
如果key为null,这始终会被散列到table[0]的桶中,即使是rehash的过程也是一样。非null的key也有可能会被散列到table[0]的位置,例如上图中key=“f”,而且相同的key在在不同的时间可能会被散列到不同的位置,这与rehash有关。
这个过程中容易发生什么问题呢?
容易产生条件竞争,如果在扩容的过程中put数据,会造成意想不到的结果。或者如果两个线程都触发了扩容,也会存在问题
这块有没有遇到过什么比较好的例子?
jdk1.8以后改成了红黑树,为什么?说一下红黑树的原理?
hashmap与hashtable的区别?
HashTable和HashMap的实现原理几乎一样,差别无非是
HashTable不允许key和value为null
HashTable是线程安全的
但是HashTable线程安全的策略实现代价却太大了,简单粗暴,get/put所有相关操作都是synchronized的,这相当于给整个哈希表加了一把大锁。
多线程访问时候,只要有一个线程访问或操作该对象,那其他线程只能阻塞,相当于将所有的操作串行化,在竞争激烈的并发场景中性能就会非常差。
篇幅有限,未完待续