电脑java模拟器(我们身处在一个什么样的世界——第一章:艰难抉择)
电脑java模拟器文章列表:
- 1、我们身处在一个什么样的世界——第一章:艰难抉择
- 2、justjavac:从辍学到成为Deno核心代码贡献者,我的十年编程生涯
- 3、Java成神及面试资源
- 4、火了15年的SONY神机PSP,最后还是输给了iPhone
- 5、鸿蒙系统全面揭秘!腾讯开发工程师不吹不擂,带你深入剖析
我们身处在一个什么样的世界——第一章:艰难抉择
是真的,我们每天都要做很多的选择,那些鸡毛蒜皮的小事,就不拿来讨论了。
主要谈谈关于大事的抉择问题。
相信每个成年人每天除了吃饭,想得最多的应该就是赚钱了。这件事甚至取代了多数男人心中的异性。
但是面临赚钱这条路的时候,我们总是选错,或者说总是喜欢把自己的欲望嫁代到这件事里面(本文只讲经验不推广任何产品)
80年代,社会上的主流观点是铁饭碗,托关系,走后门,砸锅卖铁也要找一个旱涝保收的职业。
当然,这个行为真的很能理解,哪个平头老百姓不想老老实实地过一生,平平淡淡的,都没问题。
但问题就出在这个欲望不能放到赚钱的想法里面。
以前的国营商场有很多,里面的服务员,管理员都属于单位职员,不是那种想聘哪个就招哪个。
当年很多人都往这种商场里面挤,甚至要托关系才能进。
但是还有一批人呢,就去市场经商了,俗称下海。
当然后面谁真正赚到钱,我们都知道了。
值得注意的是,你们不要以为当年下海经商是条很明智的决策!
很少人能看清,而且那个年代经商比现在更难。
虽然不用担心买家,但是光一个营业执照就能让你跑断腿,交通也不便利,很多地方连车都没有,一天就那么两趟。
治安环境也没有现在好,那时候的悍匪是连银行都敢抢的,又没有监控,只能现金交易。消息闭塞,你不会的只能问人,看报纸,没有任何系统查阅的平台。
各种骗子也很多,现在玩的这些手段,都是那时候玩剩下的
这条路上失去生命的估计都有很多。不开玩笑。
现在你看到以前做生意的赚发了,恨自己生不逢时,简直就是幼稚。
那时候最好的职业就是去商场上班,因为没人管你服务质量怎么样,投诉的地方都没有。
拿张报纸一坐一天,按月拿钱,跟坐办公室没差,夏天有风扇不用晒,冬天也能烤火。
这样的条件,你不去挤才怪,找对象,人家也看这个,看你是什么单位。做生意的是最没地位的。
直到房地产开始有火的苗头,大家才开始接受做生意这条路,而且各方面的基础建设也大致上都完善了。
各方面行情都不错了,这个时候想做生意的人就开始多了,又出现了一个词语:停薪留职。
大量在职人员,开始走上了经商的道路,基本上有点本钱得人都开始盯着这个行业了。
于是咱老百姓又有了一个想法,要有一个人流量大的门面。
于是可以看到很多的旺铺招租,一定是这家刚走另外一家就来了。
然后有钱都找不到一个地段好的门面,有的奶茶店30平左右,转让费100万老板都看不上。人家一天的营业额就2万多了。
有钱人挤不进来,于是就开始有一批人给有钱人提供项目方案。
一套PPT,就能融资几千万,你说个几百万的项目都没人正眼看你。
几千万去砸一个行业,比如网站,服务业等等。
当然再后来积累了原始资本的人就是那群玩PPT的。
现在看看,是不是又后悔没去玩PPT对吧?
但是在同时期看,会做PPT的有几个人?又有几个人敢在大老板面前,侃侃而谈,还能把他们唬住。
现在能做到这个的当然一抓一大把,但那个时期确实没几个人能做到。
大家都只想着能有个属于自己的店铺,最好就是两口子一起做,每天小钱收着,不用看任何领导的脸色,小日子不要太爽。
19年之后,大环境影响,线上的渠道是层出不穷,动不动就是月入几千万的报道。
造成了一个只要你会上网就能发财的错觉。但其实到了这个阶段,商业已经发展成熟了,普通人完全被锁死在门外。
别以为这是危言耸听,你就看现在最赚钱的工作跟以前的对比一下就知道了。
过去赚钱的岗位是策划,设计师,产品经理等,这些脑力劳动得门槛都很低,基本上受过培训的,都能很好地上手。
现在呢?自然语言,数据分析师,Java模拟器,各种程序软件开发师,这样的专业领域,没个十年八年的沉淀根本不能上岗。
这个现象也就说明了一个问题,社会已经不需要勤劳的人了。
所有人都在努力,努力就不值钱了。知识量也在不断地整体上升,你知道的大家都知道。
人和人之间的差别是资金的差别。一个500万存款的,跟一个负债几十万买房的人,他们的差别是知识量和努力都无法弥补的。
跟人相关的价值全都在贬值,包括现在比较火的程序员,他们也只是在做网络基础建设,跟十多年前的建筑工人没差。
以前的抉择已经错过了,那是真正的普通人能翻身的机会,虽然成功率也低的可怜。
按百分比来算,以前下海,做PPT的成功率肯能有个百分之3左右,现在呢?只有百分之0.003。
真没夸张,你可能不会相信,翻开手机,貌似有大量的翻身机会够自己折腾的。
但是网络是把全国最优秀,做得最好的那批人拿出来给你看。
就算14亿里面抽1万个做得最好的给你看,每天不重样地给你推,都够你看好几年。
别说我们看到的案例还都差不多,那些案例也根本没有代表性。没有学习的可能,只能看个乐。
在这个非常时期,有没有机会?适合咱老百姓的只有一个
线下服务业,还有谁说网上轻松赚钱的都是耍流氓,不可能。
只有去做线下的服务类,但不是那种洗脚按摩啥的,是上门服务之类的,现在是一片蓝海,做的人很少。具体项目自己去想。
因为现在出行麻烦,大家都是多一事不如少一事,上门服务类的基本没啥人做。
再就是这个钱赚得不怎么光彩,身边的人会对你指指点点,这个要做好心理准备。
但是赚钱你还用在乎他们的眼光?以前下海经商的,做PPT拉投资的,包括现在拍短视频的,哪个不是他们嘴里的不务正业?
人无我有,才是经商之道,别问我能赚多少钱。线下的上门服务,绝对赚的钱够还房贷。
适用人群,工作变故,房贷欠款未清者。
想轻松赚钱,还要那种动则千万上亿的,那还是去网上找那种爽文看吧,毕竟活在想象的世界里面也是一种幸福方式。
justjavac:从辍学到成为Deno核心代码贡献者,我的十年编程生涯
【CSDN 编者按】大学因学费而辍学,最困难时睡在公园长椅,有远见的母亲让他走上了编程之路,温柔智慧的妻子用爱与信任激励着他秉承初心、奋勇前行。编程十余年,他已在GitHub开源三百多个项目,项目总Star数位居全球TOP 20。从后端成功转型为前端,成为Deno核心代码贡献者的迷渡(网络ID:justJavac)在《新程序员004》之「我是程序员」板块分享了他这一路的成长与感悟。同时,也给新一代开发者留下了寄语:“学历代表过去,能力代表现在,学习能力代表未来”。
作者 | 迷渡 责编 | 张红月
出品 | 《新程序员》编辑部
2009年,Node.js&Deno之父Ryan Dahl首次在JSConf EU上介绍Node.js,从那时起,他便成为我崇拜的技术偶像。
2019年,我收到了一封来自Ryan Dahl的邮件,信中他说来中国了,想约我一起喝杯咖啡,谈谈Deno以后的发展方向。我激动的一晚上没有睡好,第二天一大早便坐高铁从天津赶到北京赴约(见图1)。
图 1 Node.js&Deno之父Ryan Dahl与justjavac的合照
回顾十多年的编程生涯,我在大学时因为学费而辍学,最困难的时候也曾经睡过天津人民公园的长椅,后来在百脑汇找了份电脑维修工作,业余时间学习了计算机相关的所有课程。结婚之后在老婆的督促下开始努力,经过十余年的付出,终于迎来了自己的Aha时刻:技术文章全网访问量破千万,如今被Node.js之父单独约见并一起开发下一代类Node.js平台——Deno。
本文节选自《新程序员004》,扫描上方二维码即可订阅
学生时代编程启蒙
初中时,我开始接触电脑,使用的第一门语言是BASIC。那时我所在的初中是我们县仅有的几个开设计算机课程的学校之一,当时电脑还是奢侈品,进入微机室上课需要穿鞋套。每个学期的计算机课程很少,两周才上一节课。还总会出现“今天微机课老师有事,这节课改成数学/语文课”的情况。课程内容也很简单,就是一些计算机的正确开关机、拼音打字、五笔打字、常用操作,并没有安排编程课。但微机教科书最后两章是BASIC编程入门,于是我在学完计算机基本操作之后就开始自学BASIC编程,编写的第一个程序是计算从0累加到100的总和。
在初三时,我的父亲给我买了一台二手电脑。我在这台电脑上编的第一个程序是VBA,主要是使用VBA脚本在Excel中处理了我整个初三上半年的成绩。闲暇之余,也会玩一些游戏,如《红色警戒》。
到了高中,学校的电脑课程主要围绕WPS和一些软件操作教程。彼时的我从计算机杂志里面扣下来一张3.5寸软盘,在电脑上安装了Pascal编译器,也进行了一些简单的编程尝试。不过家里的电脑最主要的用途还是用来玩游戏,放假时,我经常邀请同桌一起来家里玩《雷电》。但是好景不长,没过多久这台电脑平白无故的就坏了,也一直没修。到现在我也不知道这台电脑到底是年久失修坏的还是“人为的故意”损坏。总之直到高考结束,我再也没有写过程序。
人生的两个转折点:选择与放弃
当填报志愿那天来临时,我的妈妈做了一个影响我直到现在的决定,这也是我人生的第一个拐点。当时我还在犹豫填报什么专业的时候,母亲对我说:“现在比尔·盖茨是世界首富,学编程以后肯定吃香,报计算机编程专业吧”,于是我大学选择了软件工程专业。
万万没想到妈妈的话一语成谶,我果然步了比尔·盖茨的后尘——但是并没有像比尔·盖茨一样成为世界首富,而是像比尔·盖茨一样辍学了,当然这些都是后话了。
还记得2009年对我来说是最尴尬的一年,那年我花掉了家里给我本来应该交下学期学费的钱,买了一台高配的笔记本。当我打算用一年时间打工赚学费时,却被现实无情地打败了。我和3个同学一起在网上找了一个饭店服务生的工作,面试完之后HR告诉我们上岗需要穿西装。我之前从来没有穿过西装,正当我犹豫要不要买一件的时候,却接到了公司的电话,其它3个同学都应聘上了,我落榜了。
后来,我静下心来回归到了正常的大学学习与生活中。大学期间,我学习的主要课程是C、C 、C#、Delphi,也在图书馆里自学了Java、PHP、Python。个人而言,我最喜欢的语言是Java和C,于是我给自己取了一个网名叫justjavac。我接触的第一个开源软件是FireFox,这也是我头像的由来,我很欣赏FireFox挑战IE浏览器权威的故事。
随着Node.js的发布,Ryan Dahl成了我的榜样和偶像,我做梦都幻想自己将来能成为像Ryan Dahl一样的软件工程师。
于是,我开始关注国外的最新技术以及开源相关的动态。就这样大学过去了一年,我鼓起勇气向开源软件Tomcat的Servlet组件提交了个人的第一个代码补丁。那时候GitHub还没有诞生,我在查阅了很多向开源软件贡献代码的资料后,将代码补丁以邮件的形式发给了Tomcat维护者,经过几轮的讨论,我的补丁被拒绝了。虽然这次参与开源失败了,但这是我迈向开源的第一步。
大学期间,我也开始了第一次创业之旅。我的第一个创业合伙人叫徐来,他的座右铭“但行好事,莫问前程”深深的影响了我。他是我大学的班长兼舍友,当大部分同学都找到实习工作的时候,只有我在宿舍里写写程序,而他则在外面接一些做软件的私活,并让我和他一起做。后来他对我说要成立一家公司,询问我是否感兴趣一起干。那天,我们聊了很多,也聊得很投机。人生中的第一次创业便从这时展开。
没过多久,我就用到了大学自学过的几乎所有编程语言,俨然成为了一名“全能”工程师,而徐来也支持并认可我做的每一次技术选型。创业比打工要辛苦多了,最久一次工作时间是一个月只休息了一天,但一想到是为了自己而拼搏,也就不觉得累了。
大学的时光总是美好而短暂,很快就到了毕业的日子。临近毕业的前几天,老师找到我说,如果能够补齐此前拖欠的学费,可以给我补发毕业证和学位证。然而在人生的第二个拐点,我做了一个错误的决定。当时只是想着“既然我根本就没怎么去上课,为什么还要补交学费呢?”于是我拒绝了老师的要求,实则最主要的原因是当下确实没有钱,也因此没有拿到毕业证。
一万小时定律
从学校离开的两年后,我结婚了。结婚前的一个月,一直期待婚姻的我第一次有了恐婚心理。那时的我一无所有:没钱、没房、没车,甚至也没有给老婆买钻戒、拍婚纱照。
我们最初租了一间60多平米的房子,生活的大部分花销都是由老婆负责,我平时就是靠编程获得寥寥可数的工资,即使如此,老婆依然很支持我做的任何事情和决定。婚后我除了编程之外,也开始写写博客、在社区回答一些问题。
不过,有一年的结婚纪念日,我的老婆突然和我谈心时说道:“你知不知道之前咱们租房时,有一次我切着切着菜,把菜都扔地上了,在沙发上坐了一会儿才又继续切。你知道为什么吗?我在想,我要一辈子过这种日子吗?后来我想通了,既然我当初嫁给了你,就算跟你过一辈子这种日子,我也愿意”。
这段话深深地触痛了我,我不应该辜负一个深深爱着我的人,我应该做些改变。
不久后我在网上看到了一句话:一万小时定律,任何一个人只要在某个领域精益求精地钻研一万小时,那么他就能成为这个领域的专家。听上去有点像心灵鸡汤,但是不管它是“真鸡汤”还是“毒鸡汤”,我都喝定了。那晚我和老婆聊到很晚,我告诉她,“一万小时是多久?如果一个技术我每天钻研5小时,一年365天,那么一万小时差不多就是5年。而5年后我才三十岁左右,别人三十岁可能已经遇到中年危机了,而我三十岁能成为一个领域的专家。不过专家这个词比较虚,现实一点的说法就是虽然我现在一年赚不到3万,但是我一定要30岁的时候年薪30万”。
自此以后,我便把主要精力都放在了JavaScript 上,而且还更加深入的研究了 JavaScript的执行原理以及Chrome、V8、Node.js的底层机制。为了研究网页上的 JavaScript库,我开发并开源了一个Chrome插件LibrarySniffer(原 ChromeSnifferPlus),安装这个插件后,使用Chrome浏览任何网页时都会在插件页显示出当前页面用到了哪些JavaScript库。
2014年,在我办了一张双币信用卡并支付了5美元的费用后 ,LibrarySniffer终于在 Chrome Web Store上架了。同年我又开发了另一个插件ReplaceGoogleCDN,将国外的通过CDN直接引入的JavaScript资源替换为国内的镜像资源,可以达到2-50倍的加速效果。第二年,LibrarySniffer收到了一名巴西程序员提交的葡萄牙语言包,这也是我的开源项目第一次受到外国开发者的关注。
结识狼叔,深入Node.js后端
我以为LibrarySniffer能受到国外程序员关注是我的巅峰,没想到这仅仅只是开始。一个月后我收到了某个活动的邀请函,让我去他们公司做技术交流。该公司创始人说要上线一个新品,特邀我去做技术分享,如图2所示。
图 2 我的首次分享
之后,我也经常参加业界的一些开发者大会。还记得在天津举办的一场200人的开发者大会上,我在做完JavaScript前端相关主题演讲后,结识了阿里巴巴技术专家、国内知名Node.js技术布道者、《狼书:更了不起的Node.js》作者i5ting(狼叔)。
想必很多经常逛Node.js中文社区的开发者即使没听说过创始人alsotang,也一定听说过 i5ting。当得知狼叔也在天津创业时,我还是吃了一惊。天津被称为互联网的沙漠,而狼叔带领的Node.js团队可谓沙漠里面的一颗明珠。我经常使用Node.js,不过只是作为工具,真正生产环境里的后端服务依然是使用PHP或者Java。
我和狼叔深入聊了聊Node.js后端,随后狼叔更是邀请我去参观他们公司的技术团队。狼叔对我说,你研究V8那么深,其实对前端的作用不是非常大,但是对于Node.js后端则很有用。听完狼叔的劝告,我也开始在公司中引入Node.js作为后端服务,遇到问题则直接呼叫狼叔这个“免费的顾问”,几乎都可以解决。
谁曾想天有不测风云,一心研究Node.js的狼叔被合伙人给坑了。我约狼叔出来一起吃饭,心态佛系的狼叔也没有怨天尤人,只是说了句“程序员斗不过商人”。这句话我太有同感了,因为我第二次创业时也是被合伙人给坑了。我安慰他说,你虽然离开天津了,但是我继续留在天津扛下Node.js的大旗。狼叔笑道:“就算我不走,你也是天津 Node.js届的扛把子”。
狼叔比我小,平时他喊我哥,我喊他叔。在随后的几年里,每当狼叔来天津都会和我一起叙叙旧,而我如果去到了狼叔所在的城市也会找他一起聊聊天。最近几年,我在维护 Deno的过程中也向狼叔请教了很多Node.js的知识点。
图3 左起依次是umijs作者sorrycc(云谦)、i5ting(狼叔)、justjavac(迷渡)
成为Deno核心代码贡献者
2017年,我收到腾讯TFC前端大会的邀请,去分享V8、JavaScript相关内容,这是我第一次被BAT大厂邀请。会后知名前端开发者winter曾问我,“你在天津哪家公司任职,为什么会用到这么深入的V8场景”。我回应道,“其实我们公司根本用不到这些,研究V8纯粹是我的个人兴趣”。当他问为什么不去腾讯、阿里、字节跳动时,我回答说,比较恋家,娶了个天津老婆,所以也就不想去北上广了。
图4 上排中间 winter(寒冬),中排中间 justjavac(迷渡)
2018年,Ryan Dahl向社区宣布正在开发另一个JavaScript/TypeScript运行时平台——Deno。我第一时间下载了源码并编译了一个可执行文件,我在使用后发现Deno的Bug还非常多,毕竟才刚开发不久。彼时网上对Deno也存在两种截然不同的态度,一种是崇拜,另一种是质疑,甚至出现了Deno的issue被垃圾信息充斥的局面。但是,只顾在 issue上发泄不满解决不了任何问题。彼时,我便在思考,既然Deno问题这么多,为什么不帮它改进呢?于是,我开始了Deno开发之旅。
起初我也仅仅是帮Deno改一下Bug,但当我得知Deno是想做一个兼容浏览器及Web API平台后,我便新建了一个开源项目,为Deno开发WPT(Web-Platform-Tests Suite,Web平台测试套件),然后帮助Deno实现和改进了url、console、encode/decode、timmer等API。
随着越来越多的开发者开始使用Deno,新问题不断涌现。由于TypeScript的整套工具链都是基于Node.js开发,这就导致了当使用VSCode开发Deno时会出现波浪线标红警告,于是我开发了一个 VSCode扩展和一个TypeScript Service Plugin来解决这个问题,很快这个扩展便受到了国内外很多社区的推荐,甚至得到Deno之父Ryan Dahl的关注。
2019年,Ryan Dahl和我见面时也当面感谢我为Deno开发了这个扩展。与此同时,另一位开发者axetroy(铁手) 也一直为这个扩展添加功能。后来我老婆怀孕了,我对社区的参与也少了很多,于是axetroy基于我的代码新建了一个项目继续开发并完善这个扩展。
在Deno发布1.0正式版的当天,我联系Ryan Dahl并希望把该扩展放到Deno的官方仓库。我目前最遗憾的一件事就是由于当时选择了直接把我的项目复制到官方仓库而导致了axetroy代码没有合并进来。
后来,我又搭建了Deno中国加速镜像服务,让国内开发者更加方便地学习和使用 Deno。将deno.dev域名送给Ryan Dahl 作为Deno Deploy的官方域名。开发了Deno的多版本管理工具dvm(Deno Version Manager)。
这几年我不断被各种技术研讨会、组织、企业、个人邀请去做Deno技术演讲。
然而我并没有止步于Deno,2020年华为开源了HarmonyOS(鸿蒙)系统,当我得知鸿蒙系统也是用了一个轻量级JavaScript引擎时顿时来了兴致,当晚便下载了鸿蒙的源码开始研究,并写了一篇逐行分析鸿蒙JavaScript框架源码的文章,还为鸿蒙修复了多个bug,不久后收到了鸿蒙团队寄来的一个开发版,从此以后再也不用在模拟器上调试了,而可以直接使用真机了。
总结
自我第一次参与开源到现在十余年,已经在GitHub上开源300多个项目,根据第三方数据统计目前获得的总Star数排名全球前20。我感觉自己非常幸运,从后端转型到前端后就赶上了JavaScript的飞速发展,也见证了HTML5、ES6、CSS3等技术的发展历程。最后想送给每位开发者一句话“学历代表过去,能力代表现在,学习能力代表未来”。
二十年前,《新程序员》创刊时,我们要全面关注软件人的成长。今天,我们依然初心不变:在一行行代码的背后,是一颗颗鲜活的开发者想要改变世界的雄心壮志。
因此,《新程序员004》从 C 之父 Bjarne Stroustrup、C# 之父 Anders Hejlsberg、MySQL 之父 Michael "Monty" Widenius、PostgreSQL 全球开发组联合创始人 Bruce Momjian 等程序员祖师爷,到阿里巴巴副总裁贾扬清、指令集创始人兼董事长潘爱民、Vue.js 作者尤雨溪……48 位技术大咖,共创我们的程序人生、我们的技术时代。《新程序员004》已全面上市,欢迎订阅!
Java成神及面试资源
大家可以针对性的学习,提升自己。对于答案 ,并没有标准的。希望可以通过下面列出问题自己学习整理并总结。这样应该更有意义
基本概念
操作系统中 heap 和 stack 的区别
什么是基于注解的切面实现
什么是 对象/关系 映射集成模块
什么是 Java 的反射机制
什么是 ACID
BS与CS的联系与区别
Cookie 和 Session的区别
fail-fast 与 fail-safe 机制有什么区别
get 和 post请求的区别
Interface 与 abstract 类的区别
IOC的优点是什么
IO 和 NIO的区别,NIO优点
Java 8 / Java 7 为我们提供了什么新功能
什么是竞态条件? 举个例子说明。
JRE、JDK、JVM 及 JIT 之间有什么不同
MVC的各个部分都有那些技术来实现?如何实现?
RPC 通信和 RMI 区别
什么是 Web Service(Web服务)
JSWDL开发包的介绍。JAXP、JAXM的解释。SOAP、UDDI,WSDL解释。
WEB容器主要有哪些功能? 并请列出一些常见的WEB容器名字。
一个”.java”源文件中是否可以包含多个类(不是内部类)?有什么限制
简单说说你了解的类加载器。是否实现过类加载器
解释一下什么叫AOP(面向切面编程)
请简述 Servlet 的生命周期及其相关的方法
请简述一下 Ajax 的原理及实现步骤
简单描述Struts的主要功能
什么是 N 层架构
什么是CORBA?用途是什么
什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”
什么是正则表达式?用途是什么?哪个包使用正则表达式来实现模式匹配
什么是懒加载(Lazy Loading)
什么是尾递归,为什么需要尾递归
什么是控制反转(Inversion of Control)与依赖注入(Dependency Injection)
关键字
finalize
什么是finalize()方法
finalize()方法什么时候被调用
析构函数(finalization)的目的是什么
final 和 finalize 的区别
final
final关键字有哪些用法
final 与 static 关键字可以用于哪里?它们的作用是什么
final, finally, finalize的区别
final、finalize 和 finally 的不同之处?
能否在运行时向 static final 类型的赋值
使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变
一个类被声明为final类型,表示了什么意思
throws, throw, try, catch, finally分别代表什么意义
Java 有几种修饰符?分别用来修饰什么
volatile
volatile 修饰符的有过什么实践
volatile 变量是什么?volatile 变量和 atomic 变量有什么不同
volatile 类型变量提供什么保证?能使得一个非原子操作变成原子操作吗
能创建 volatile 数组吗?
transient变量有什么特点
super什么时候使用
public static void 写成 static public void会怎样
说明一下public static void main(String args[])这段声明里每个关键字的作用
请说出作用域public, private, protected, 以及不写时的区别
sizeof 是Java 的关键字吗
static
static class 与 non static class的区别
static 关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法
静态类型有什么特点
main() 方法为什么必须是静态的?能不能声明 main() 方法为非静态
是否可以从一个静态(static)方法内部发出对非静态(non-static)方法的调用
静态变量在什么时候加载?编译期还是运行期?静态代码块加载的时机呢
成员方法是否可以访问静态变量?为什么静态方法不能访问成员变量
switch
switch 语句中的表达式可以是什么类型数据
switch 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上
while 循环和 do 循环有什么不同
操作符
&操作符和&&操作符有什么区别?
a = a b 与 a = b 的区别?
逻辑操作符 (&,|,^)与条件操作符(&&,||)的区别
3*0.1 == 0.3 将会返回什么?true 还是 false?
float f=3.4; 是否正确?
short s1 = 1; s1 = s1 1;有什么错?
数据结构
基础类型(Primitives)
基础类型(Primitives)与封装类型(Wrappers)的区别在哪里
简述九种基本数据类型的大小,以及他们的封装类
int 和 Integer 哪个会占用更多的内存? int 和 Integer 有什么区别?parseInt()函数在什么时候使用到
float和double的默认值是多少
如何去小数四舍五入保留小数点后两位
char 型变量中能不能存贮一个中文汉字,为什么
类型转换
怎样将 bytes 转换为 long 类型
怎么将 byte 转换为 String
如何将数值型字符转换为数字
我们能将 int 强制转换为 byte 类型的变量吗?如果该值大于 byte 类型的范围,将会出现什么现象
能在不进行强制转换的情况下将一个 double 值赋值给 long 类型的变量吗
类型向下转换是什么
数组
如何权衡是使用无序的数组还是有序的数组
怎么判断数组是 null 还是为空
怎么打印数组? 怎样打印数组中的重复元素
Array 和 ArrayList有什么区别?什么时候应该使用Array而不是ArrayList
数组和链表数据结构描述,各自的时间复杂度
数组有没有length()这个方法? String有没有length()这个方法
队列
队列和栈是什么,列出它们的区别
BLockingQueue是什么
简述 ConcurrentLinkedQueue LinkedBlockingQueue 的用处和不同之处。
ArrayList、Vector、LinkedList的存储性能和特性
String
StringBuffer
ByteBuffer 与 StringBuffer有什么区别
HashMap
HashMap的工作原理是什么
内部的数据结构是什么
HashMap 的 table的容量如何确定?loadFactor 是什么? 该容量如何变化?这种变化会带来什么问题?
HashMap 实现的数据结构是什么?如何实现
HashMap 和 HashTable、ConcurrentHashMap 的区别
HashMap的遍历方式及效率
HashMap、LinkedMap、TreeMap的区别
如何决定选用HashMap还是TreeMap
如果HashMap的大小超过了负载因子(load factor)定义的容量,怎么办
HashMap 是线程安全的吗?并发下使用的 Map 是什么,它们内部原理分别是什么,比如存储方式、 hashcode、扩容、 默认容量等
HashSet
HashSet和TreeSet有什么区别
HashSet 内部是如何工作的
WeakHashMap 是怎么工作的?
Set
Set 里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用 == 还是 equals()? 它们有何区别?
TreeMap:TreeMap 是采用什么树实现的?TreeMap、HashMap、LindedHashMap的区别。TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素?
TreeSet:一个已经构建好的 TreeSet,怎么完成倒排序。
EnumSet 是什么
Hash算法
Hashcode 的作用
简述一致性 Hash 算法
有没有可能 两个不相等的对象有相同的 hashcode?当两个对象 hashcode 相同怎么办?如何获取值对象
为什么在重写 equals 方法的时候需要重写 hashCode 方法?equals与 hashCode 的异同点在哪里
a.hashCode() 有什么用?与 a.equals(b) 有什么关系
hashCode() 和 equals() 方法的重要性体现在什么地方
Object:Object有哪些公用方法?Object类hashcode,equals 设计原则? sun为什么这么设计?Object类的概述
如何在父类中为子类自动完成所有的 hashcode 和 equals 实现?这么做有何优劣。
可以在 hashcode() 中使用随机数字吗?
LinkedHashMap
LinkedHashMap 和 PriorityQueue 的区别是什么
List
List, Set, Map三个接口,存取元素时各有什么特点
List, Set, Map 是否继承自 Collection 接口
遍历一个 List 有哪些不同的方式
LinkedList
LinkedList 是单向链表还是双向链表
LinkedList 与 ArrayList 有什么区别
描述下 Java 中集合(Collections),接口(Interfaces),实现(Implementations)的概念。LinkedList 与 ArrayList 的区别是什么?
插入数据时,ArrayList, LinkedList, Vector谁速度较快?
ArrayList
ArrayList 和 HashMap 的默认大小是多数
ArrayList 和 LinkedList 的区别,什么时候用 ArrayList?
ArrayList 和 Set 的区别?
ArrayList, LinkedList, Vector的区别
ArrayList是如何实现的,ArrayList 和 LinkedList 的区别
ArrayList如何实现扩容
Array 和 ArrayList 有何区别?什么时候更适合用Array
说出ArraList,Vector, LinkedList的存储性能和特性
Map
Map, Set, List, Queue, Stack
Map 接口提供了哪些不同的集合视图
为什么 Map 接口不继承 Collection 接口
Collections
介绍Java中的Collection FrameWork。集合类框架的基本接口有哪些
Collections类是什么?Collection 和 Collections的区别?Collection、Map的实现
集合类框架的最佳实践有哪些
为什么 Collection 不从 Cloneable 和 Serializable 接口继承
说出几点 Java 中使用 Collections 的最佳实践?
Collections 中 遗留类 (HashTable、Vector) 和 现有类的区别
什么是 B 树,B-树,列出实际的使用场景。
接口
Comparator 与 Comparable 接口是干什么的?列出它们的区别
对象
拷贝(clone)
如何实现对象克隆
深拷贝和浅拷贝区别
深拷贝和浅拷贝如何实现激活机制
写clone()方法时,通常都有一行代码,是什么
比较
在比较对象时,”==” 运算符和 equals 运算有何区别
如果要重写一个对象的equals方法,还要考虑什么
两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对
构造器
构造器链是什么
创建对象时构造器的调用顺序
不可变对象
什么是不可变象(immutable object)
为什么 Java 中的 String 是不可变的(Immutable)
如何构建不可变的类结构?关键点在哪里
能创建一个包含可变对象的不可变对象吗
如何对一组对象进行排序
方法
构造器(constructor)是否可被重写(override)
方法可以同时即是 static 又是 synchronized 的吗
abstract 的 method是否可同时是 static,是否可同时是 native,是否可同时是synchronized
Java支持哪种参数传递类型
一个对象被当作参数传递到一个方法,是值传递还是引用传递
当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递
我们能否重载main()方法
如果main方法被声明为private会怎样
GC
概念
GC是什么?为什么要有GC
什么时候会导致垃圾回收
GC是怎么样运行的
新老以及永久区是什么
GC 有几种方式?怎么配置
什么时候一个对象会被GC? 如何判断一个对象是否存活
System.gc() Runtime.gc()会做什么事情? 能保证 GC 执行吗
垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?
Minor GC 、Major GC、Young GC 与 Full GC分别在什么时候发生
垃圾回收算法的实现原理
如果对象的引用被置为null,垃圾收集器是否会立即释放对象占用的内存?
垃圾回收的最佳做法是什么
GC收集器有哪些
垃圾回收器的基本原理是什么?
串行(serial)收集器和吞吐量(throughput)收集器的区别是什么
Serial 与 Parallel GC之间的不同之处
CMS 收集器 与 G1 收集器的特点与区别
CMS垃圾回收器的工作过程
JVM 中一次完整的 GC 流程是怎样的? 对象如何晋升到老年代
吞吐量优先和响应优先的垃圾收集器选择
GC策略
举个实际的场景,选择一个GC策略
JVM的永久代中会发生垃圾回收吗
收集方法
标记清除、标记整理、复制算法的原理与特点?分别用在什么地方
如果让你优化收集方法,有什么思路
JVM
参数
说说你知道的几种主要的jvm 参数
-XX: UseCompressedOops 有什么作用
类加载器(ClassLoader)
Java 类加载器都有哪些
JVM如何加载字节码文件
内存管理
JVM内存分哪几个区,每个区的作用是什么
一个对象从创建到销毁都是怎么在这些部分里存活和转移的
解释内存中的栈(stack)、堆(heap)和方法区(method area)的用法
JVM中哪个参数是用来控制线程的栈堆栈小
简述内存分配与回收策略
简述重排序,内存屏障,happen-before,主内存,工作内存
Java中存在内存泄漏问题吗?请举例说明
简述 Java 中软引用(SoftReferenc)、弱引用(WeakReference)和虚引用
内存映射缓存区是什么
JVM
jstack,jstat,jmap,jconsole怎么用
32 位 JVM 和 64 位 JVM 的最大堆内存分别是多数?32 位和 64 位的 JVM,int 类型变量的长度是多数?
怎样通过 Java 程序来判断 JVM 是 32 位 还是 64 位
JVM自身会维护缓存吗?是不是在堆中进行对象分配,操作系统的堆还是JVM自己管理堆
什么情况下会发生栈内存溢出
双亲委派模型是什么
多线程
基本概念
什么是线程
多线程的优点
多线程的几种实现方式
用 Runnable 还是 Thread
什么是线程安全
Vector, SimpleDateFormat 是线程安全类吗
什么 Java 原型不是线程安全的
哪些集合类是线程安全的
多线程中的忙循环是什么
如何创建一个线程
编写多线程程序有几种实现方式
什么是线程局部变量
线程和进程有什么区别?进程间如何通讯,线程间如何通讯
什么是多线程环境下的伪共享(false sharing)
同步和异步有何异同,在什么情况下分别使用他们?举例说明
Current
ConcurrentHashMap 和 Hashtable的区别
ArrayBlockingQueue, CountDownLatch的用法
ConcurrentHashMap的并发度是什么
CyclicBarrier 和 CountDownLatch有什么不同?各自的内部原理和用法是什么
Semaphore的用法
Thread
启动一个线程是调用 run() 还是 start() 方法?start() 和 run() 方法有什么区别
调用start()方法时会执行run()方法,为什么不能直接调用run()方法
sleep() 方法和对象的 wait() 方法都可以让线程暂停执行,它们有什么区别
yield方法有什么作用?sleep() 方法和 yield() 方法有什么区别
Java 中如何停止一个线程
stop() 和 suspend() 方法为何不推荐使用
如何在两个线程间共享数据
如何强制启动一个线程
如何让正在运行的线程暂停一段时间
什么是线程组,为什么在Java中不推荐使用
你是如何调用 wait(方法的)?使用 if 块还是循环?为什么
生命周期
有哪些不同的线程生命周期
线程状态,BLOCKED 和 WAITING 有什么区别
画一个线程的生命周期状态图
ThreadLocal 用途是什么,原理是什么,用的时候要注意什么
ThreadPool
线程池是什么?为什么要使用它
如何创建一个Java线程池
ThreadPool用法与优势
提交任务时,线程池队列已满时会发会生什么
newCache 和 newFixed 有什么区别?简述原理。构造函数的各个参数的含义是什么,比如 coreSize, maxsize 等
线程池的实现策略
线程池的关闭方式有几种,各自的区别是什么
线程池中submit() 和 execute()方法有什么区别?
线程调度
Java中用到的线程调度算法是什么
什么是多线程中的上下文切换
你对线程优先级的理解是什么
什么是线程调度器 (Thread Scheduler) 和时间分片 (Time Slicing)
线程同步
请说出你所知的线程同步的方法
synchronized 的原理是什么
synchronized 和 ReentrantLock 有什么不同
什么场景下可以使用 volatile 替换 synchronized
有T1,T2,T3三个线程,怎么确保它们按顺序执行?怎样保证T2在T1执行完后执行,T3在T2执行完后执行
同步块内的线程抛出异常会发生什么
当一个线程进入一个对象的 synchronized 方法A 之后,其它线程是否可进入此对象的 synchronized 方法B
使用 synchronized 修饰静态方法和非静态方法有什么区别
如何从给定集合那里创建一个 synchronized 的集合
锁
Java Concurrency API 中 的 Lock 接口是什么?对比同步它有什么优势
Lock 与 Synchronized 的区别?Lock 接口比 synchronized 块的优势是什么
ReadWriteLock是什么?
锁机制有什么用
什么是乐观锁(Optimistic Locking)?如何实现乐观锁?如何避免ABA问题
解释以下名词:重排序,自旋锁,偏向锁,轻量级锁,可重入锁,公平锁,非公平锁,乐观锁,悲观锁
什么时候应该使用可重入锁
简述锁的等级方法锁、对象锁、类锁
Java中活锁和死锁有什么区别?
什么是死锁(Deadlock)?导致线程死锁的原因?如何确保 N 个线程可以访问 N 个资源同时又不导致死锁
死锁与活锁的区别,死锁与饥饿的区别
怎么检测一个线程是否拥有锁
如何实现分布式锁
有哪些无锁数据结构,他们实现的原理是什么
读写锁可以用于什么应用场景
Executors类是什么? Executor和Executors的区别
什么是Java线程转储(Thread Dump),如何得到它
如何在Java中获取线程堆栈
说出 3 条在 Java 中使用线程的最佳实践
在线程中你怎么处理不可捕捉异常
实际项目中使用多线程举例。你在多线程环境中遇到的常见的问题是什么?你是怎么解决它的
请说出与线程同步以及线程调度相关的方法
程序中有3个 socket,需要多少个线程来处理
假如有一个第三方接口,有很多个线程去调用获取数据,现在规定每秒钟最多有 10 个线程同时调用它,如何做到
如何在 Windows 和 Linux 上查找哪个线程使用的 CPU 时间最长
如何确保 main() 方法所在的线程是 Java 程序最后结束的线程
非常多个线程(可能是不同机器),相互之间需要等待协调才能完成某种工作,问怎么设计这种协调方案
你需要实现一个高效的缓存,它允许多个用户读,但只允许一个用户写,以此来保持它的完整性,你会怎样去实现它
异常
基本概念
Error 和 Exception有什么区别
UnsupportedOperationException是什么
NullPointerException 和 ArrayIndexOutOfBoundException 之间有什么相同之处
什么是受检查的异常,什么是运行时异常
运行时异常与一般异常有何异同
简述一个你最常见到的runtime exception(运行时异常)
finally
finally关键词在异常处理中如何使用
如果执行finally代码块之前方法返回了结果,或者JVM退出了,finally块中的代码还会执行吗
try里有return,finally还执行么?那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后
在什么情况下,finally语句不会执行
IO
File
File类型中定义了什么方法来创建一级目录
File类型中定义了什么方法来判断一个文件是否存在
流
为了提高读写性能,可以采用什么流
Java中有几种类型的流
JDK 为每种类型的流提供了一些抽象类以供继承,分别是哪些类
对文本文件操作用什么I/O流
对各种基本数据类型和String类型的读写,采用什么流
能指定字符编码的 I/O 流类型是什么
序列化
什么是序列化?如何实现 Java 序列化及注意事项
Serializable 与 Externalizable 的区别
Socket
socket 选项 TCP NO DELAY 是指什么
Socket 工作在 TCP/IP 协议栈是哪一层
TCP、UDP 区别及 Java 实现方式
说几点 IO 的最佳实践
直接缓冲区与非直接缓冲器有什么区别?
怎么读写 ByteBuffer?ByteBuffer 中的字节序是什么
当用System.in.read(buffer)从键盘输入一行n个字符后,存储在缓冲区buffer中的字节数是多少
如何使用扫描器类(Scanner Class)令牌化
面向对象编程(OOP)
解释下多态性(polymorphism),封装性(encapsulation),内聚(cohesion)以及耦合(coupling)
多态的实现原理
封装、继承和多态是什么
对象封装的原则是什么?
类
获得一个类的类对象有哪些方式
重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?
说出几条 Java 中方法重载的最佳实践
抽象类
抽象类和接口的区别
抽象类中是否可以有静态的main方法
抽象类是否可实现(implements)接口
抽象类是否可继承具体类(concrete class)
匿名类(Anonymous Inner Class)
匿名内部类是否可以继承其它类?是否可以实现接口
内部类
内部类分为几种
内部类可以引用它的包含类(外部类)的成员吗
请说一下 Java 中为什么要引入内部类?还有匿名内部类
继承
继承(Inheritance)与聚合(Aggregation)的区别在哪里
继承和组合之间有什么不同
为什么类只能单继承,接口可以多继承
存在两个类,B 继承 A,C 继承 B,能将 B 转换为 C 么?如 C = (C) B
如果类 a 继承类 b,实现接口c,而类 b 和接口 c 中定义了同名变量,请问会出现什么问题
接口
接口是什么
接口是否可继承接口
为什么要使用接口而不是直接使用具体类?接口有什么优点
泛型
泛型的存在是用来解决什么问题
泛型的常用特点
List能否转为List
工具类
日历
Calendar Class的用途
如何在Java中获取日历类的实例
解释一些日历类中的重要方法
GregorianCalendar 类是什么
SimpleTimeZone 类是什么
Locale类是什么
如何格式化日期对象
如何添加小时(hour)到一个日期对象(Date Objects)
如何将字符串 YYYYMMDD 转换为日期
Math
Math.round()什么作用?Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?
XML
XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式?DOM 和 SAX 解析器有什么不同?
Java解析XML的方式
用 jdom 解析 xml 文件时如何解决中文问题?如何解析
你在项目中用到了 XML 技术的哪些方面?如何实现
动态代理
描述动态代理的几种实现方式,分别说出相应的优缺点
设计模式
什么是设计模式(Design Patterns)?你用过哪种设计模式?用在什么场合
你知道哪些商业级设计模式?
哪些设计模式可以增加系统的可扩展性
单例模式
除了单例模式,你在生产环境中还用过什么设计模式?
写 Singleton 单例模式
单例模式的双检锁是什么
如何创建线程安全的 Singleton
什么是类的单例模式
写出三种单例模式实现
适配器模式
适配器模式是什么?什么时候使用
适配器模式和代理模式之前有什么不同
适配器模式和装饰器模式有什么区别
什么时候使用享元模式
什么时候使用组合模式
什么时候使用访问者模式
什么是模板方法模式
请给出1个符合开闭原则的设计模式的例子
开放问题
用一句话概括 Web 编程的特点
Google是如何在一秒内把搜索结果返回给用户
哪种依赖注入方式你建议使用,构造器注入,还是 Setter方法注入
树(二叉或其他)形成许多普通数据结构的基础。请描述一些这样的数据结构以及何时可以使用它们
某一项功能如何设计
线上系统突然变得异常缓慢,你如何查找问题
什么样的项目不适合用框架
新浪微博是如何实现把微博推给订阅者
简要介绍下从浏览器输入 URL 开始到获取到请求界面之后 Java Web 应用中发生了什么
请你谈谈SSH整合
高并发下,如何做到安全的修改同一行数据
12306网站的订票系统如何实现,如何保证不会票不被超卖
网站性能优化如何优化的
聊了下曾经参与设计的服务器架构
请思考一个方案,实现分布式环境下的 countDownLatch
请思考一个方案,设计一个可以控制缓存总体大小的自动适应的本地缓存
在你的职业生涯中,算得上最困难的技术挑战是什么
如何写一篇设计文档,目录是什么
大写的O是什么?举几个例子
编程中自己都怎么考虑一些设计原则的,比如开闭原则,以及在工作中的应用
解释一下网络应用的模式及其特点
设计一个在线文档系统,文档可以被编辑,如何防止多人同时对同一份文档进行编辑更新
说出数据连接池的工作机制是什么
怎么获取一个文件中单词出现的最高频率
描述一下你最常用的编程风格
如果有机会重新设计你们的产品,你会怎么做
如何搭建一个高可用系统
如何启动时不需输入用户名与密码
如何在基于Java的Web项目中实现文件上传和下载
如何实现一个秒杀系统,保证只有几位用户能买到某件商品。
如何实现负载均衡,有哪些算法可以实现
如何设计一个购物车?想想淘宝的购物车如何实现的
如何设计一套高并发支付方案,架构如何设计
如何设计建立和保持 100w 的长连接
如何避免浏览器缓存。
如何防止缓存雪崩
如果AB两个系统互相依赖,如何解除依
如果有人恶意创建非法连接,怎么解决
如果有几十亿的白名单,每天白天需要高并发查询,晚上需要更新一次,如何设计这个功能
如果系统要使用超大整数(超过long长度范围),请你设计一个数据结构来存储这种超大型数字以及设计一种算法来实现超大整数加法运算)
如果要设计一个图形系统,请你设计基本的图形元件(Point,Line,Rectangle,Triangle)的简单实现
如果让你实现一个并发安全的链表,你会怎么做
应用服务器与WEB 服务器的区别?应用服务器怎么监控性能,各种方式的区别?你使用过的应用服务器优化技术有哪些
大型网站在架构上应当考虑哪些问题
有没有处理过线上问题?出现内存泄露,CPU利用率标高,应用无响应时如何处理的
最近看什么书,印象最深刻的是什么
描述下常用的重构技巧
你使用什么版本管理工具?分支(Branch)与标签(Tag)之间的区别在哪里
你有了解过存在哪些反模式(Anti-Patterns)吗
你用过的网站前端优化的技术有哪些
如何分析Thread dump
你如何理解AOP中的连接点(Joinpoint)、切点(Pointcut)、增强(Advice)、引介(Introduction)、织入(Weaving)、切面(Aspect)这些概念
你是如何处理内存泄露或者栈溢出问题的
你们线上应用的 JVM 参数有哪些
怎么提升系统的QPS和吞吐量
知识面
解释什么是 MESI 协议(缓存一致性)
谈谈 reactor 模型
Java 9 带来了怎样的新功能
Java 与 C 对比,C 或 Java 中的异常处理机制的简单原理和应用
简单讲讲 Tomcat 结构,以及其类加载器流程
虚拟内存是什么
阐述下 SOLID 原则
请简要讲一下你对测试驱动开发(TDD)的认识
CDN实现原理
Maven 和 ANT 有什么区别
UML中有哪些常用的图
Linux
Linux 下 IO 模型有几种,各自的含义是什么。
Linux 系统下你关注过哪些内核参数,说说你知道的
Linux 下用一行命令查看文件的最后五行
平时用到哪些 Linux 命令
用一行命令输出正在运行的 Java 进程
使用什么命令来确定是否有 Tomcat 实例运行在机器上
什么是 N 1 难题
什么是 paxos 算法
什么是 restful,讲讲你理解的 restful
什么是 zab 协议
什么是领域模型(domain model)?贫血模型(anaemic domain model) 和充血模型(rich domain model)有什么区别
什么是领域驱动开发(Domain Driven Development)
介绍一下了解的 Java 领域的 Web Service 框架
Web Server、Web Container 与 Application Server 的区别是什么
微服务(MicroServices)与巨石型应用(Monolithic Applications)之间的区别在哪里
描述 Cookie 和 Session 的作用,区别和各自的应用范围,Session工作原理
你常用的持续集成(Continuous Integration)、静态代码分析(Static Code Analysis)工具有哪些
简述下数据库正则化(Normalizations)
KISS,DRY,YAGNI 等原则是什么含义
分布式事务的原理,优缺点,如何使用分布式事务?
布式集群下如何做到唯一序列号
网络
HTTPS 的加密方式是什么,讲讲整个加密解密流程
HTTPS和HTTP的区别
HTTP连接池实现原理
HTTP集群方案
Nginx、lighttpd、Apache三大主流 Web服务器的区别
是否看过框架的一些代码
持久层设计要考虑的问题有哪些?你用过的持久层框架有哪些
数值提升是什么
你能解释一下里氏替换原则吗
你是如何测试一个应用的?知道哪些测试框架
传输层常见编程协议有哪些?并说出各自的特点
编程题
计算加班费
加班10小时以下加班费是时薪的1.5倍。加班10小时或以上,按4元/时算。提示:(一个月工作26天,一天正常工作8小时)
计算1000月薪,加班9小时的加班费
计算2500月薪,加班11小时的加班费
计算1000月薪,加班15小时的加班费
卖东西
一家商场有红苹果和青苹果出售。(红苹果5元/个,青苹果4元/个)。
模拟一个进货。红苹果跟青苹果各进200个。
模拟一个出售。红苹果跟青苹果各买出10个。每卖出一个苹果需要进行统计。
提示:一个苹果是一个单独的实体。
日期提取
有这样一个时间字符串:2008-8-8 20:08:08 , 请编写能够匹配它的正则表达式,并编写Java代码将日期后面的时分秒提取出来,即:20:08:08
线程
8设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。
用Java写一个多线程程序,如写四个线程,二个加1,二个对一个变量减一,输出
wait-notify 写一段代码来解决生产者-消费者问题
数字
判断101-200之间有多少个素数,并输出所有素数
用最有效率的方法算出2乘以17等于多少
有 1 亿个数字,其中有 2 个是重复的,快速找到它,时间和空间要最优
2 亿个随机生成的无序整数,找出中间大小的值
10 亿个数字里里面找最小的 10 个
1到1亿的自然数,求所有数的拆分后的数字之和,如286 拆分成2、8、6,如1到11拆分后的数字之和 => 1 … 9 1 0 1 1
一个数如果恰好等于它的因子之和,这个数就称为 “完数 “。例如6=1+2+3.编程 找出1000以内的所有完数
一个数组中所有的元素都出现了三次,只有一个元素出现了一次找到这个元素
一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在 第10次落地时,共经过多少米?第10次反弹多高?
求100-1000内质数的和
求1到100的和的平均数
求s=a a aaa aaaa aa…a的值,其中a是一个数字。例如2 22 222 2222 22222(此时共有5个数相加),几个数相加有键盘控制。 求出1到100的和
算出1到40的质数,放进数组里
显示放组里的数
找出第[5]个数
删除第[9]个数,再显示删除后的第[9]个
有 3n 1 个数字,其中 3n 个中是重复的,只有 1 个是不重复的,怎么找出来。
有一组数1.1.2.3.5.8.13.21.34。写出程序随便输入一个数就能给出和前一组数字同规律的头5个数
计算指定数字的阶乘
开发 Fizz Buzz
给定一个包含 N 个整数的数组,找出丢失的整数
一个排好序的数组,找出两数之和为m的所有组合
将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。
打印出所有的 “水仙花数 “,所谓 “水仙花数 “是指一个三位数,其各位数字立方和等于该数本身。例如:153是一个 “水仙花数 “,因为153=1的三次方+5的三次方+3的三次方
原地交换两个变量的值
找出4字节整数的中位数
找到整数的平方根
实现斐波那契
网络
用Java Socket编程,读服务器几个字符,再写入本地显示
反射
反射机制提供了什么功能?
反射是如何实现的
哪里用到反射机制
反射中 Class.forName 和 ClassLoader 区别
反射创建类实例的三种方式是什么
如何通过反射调用对象的方法
如何通过反射获取和设置对象私有字段的值
反射机制的优缺点
数据库
写一段 JDBC 连Oracle的程序,并实现数据查询
算法
50个人围坐一圈,当数到三或者三的倍数出圈,问剩下的人是谁,原来的位置是多少
实现一个电梯模拟器用
写一个冒泡排序
写一个折半查找
随机产生20个不能重复的字符并排序
写一个函数,传入 2 个有序的整数数组,返回一个有序的整数数组
写一段代码在遍历 ArrayList 时移除一个元素
古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少
约瑟芬环游戏
正则
请编写一段匹配IP地址的正则表达式
写出一个正则表达式来判断一个字符串是否是一个数字
字符串
写一个方法,入一个文件名和一个字符串,统计这个字符串在这个文件中出现的次数。
写一个程序找出所有字符串的组合,并检查它们是否是回文串
写一个字符串反转函数,输入abcde转换成edcba代码
小游戏,倒转句子中的单词
将GB2312编码的字符串转换为ISO-8859-1编码的字符串
请写一段代码来计算给定文本内字符“A”的个数。分别用迭代和递归两种方式
编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。 但是要保证汉字不被截半个,如“我ABC”4,应该截为“我AB”,输入“我ABC汉DEF”,6,应该输出为“我ABC”而不是“我ABC 汉的半个”
给定 2 个包含单词列表(每行一个)的文件,编程列出交集
打印出一个字符串的所有排列
将一个键盘输入的数字转化成中文输出(例如:输入1234567,输出:一百二拾三万四千五百六拾七)
在Web应用开发过程中经常遇到输出某种编码的字符,如从 GBK 到 ISO8859-1等,如何输出一个某种编码的字符串
日期
计算两个日期之间的差距
火了15年的SONY神机PSP,最后还是输给了iPhone
难以置信, PSP 已经是 15 年前的东西了。
今年是 PSP 上市 15 周年。2004 年 12 月 12 日,初代 PSP 在日本本土首先开售。开价 19800 日元,发售当天即卖就台。可如果没有一记来自友商的“背刺”,历史也许不会如此发展。
索尼 VS 任天堂,史上最凶掌机战争
这是 PSP 的第一次实机亮相。
在那次发布会上,索尼几乎公开了关于 PSP 的一切,但就是没说发售日和价格。可等到原定公布发售计划的 9 月 21 日,任天堂突然搞了个精准狙击:就在索尼发布会前 1 个小时,新掌机 NDS 发售信息公布, 12月2日上市,定价 15000 日元。
索尼被杀得猝不及防。不光对手的定价大幅低于预期,12 月 2 日这个上市日期,也完全是贴着索尼定的(当年 12 月 3 号刚好是 PS 系列诞生 10 周年)。结果原定下午 3 点半开始的发布会,居然硬是以“高层迟到”为由推后了 17 分钟。PSP 价格、发售日两大关键信息也一并欠奉,直到接近一个月后的 10 月 27 号才公布。
War, war never changes……在这场掌机战争里, PSP 可以说是一力降十会:当时看来极为先进的 UMD 光盘,和远超 NDS ,一度让老任股价闻风而落的图形性能,都让不少评论家以为,索尼已经坐稳了第七世代掌机王的位子。
(PSP的画面表现,即便是后续的3DS也难以招架)
可 NDS 和它根本就不在一个大气层里。面对主机级画质的《山脊赛车》,任天堂扔出来的居然是《任天狗》和《脑锻炼》,两个 2000 万爆卖级别的……小游戏。
任索两家从此走上截然不同的道路:任天堂一头扎进了广阔的异质市场,除了大脑锻炼系列,《超执刀》系列的触摸笔、和以《任天狗》为代表的声控游戏,都让人眼前一亮。
索尼则越走越硬核,画面精细度和游戏特效节节攀升,大作频出。《战神:奥林匹斯之链》、《第三次生日》之类画面巅峰,是不少人心中的经典。
( QTE 小游戏就不放了,懂的都懂)
走到中期,索尼更从卡普空手里撬来了《怪物猎人》系列,掀起一时联机热潮。怪猎在 PSP 上一共出了 3 代 4 作,合计销量 1400 万。在学校和同学偷偷联机狩猎,放假在家一个人平推战神,估计是不少玩家的青春回忆。
终其一生,PSP 在全球一共售出 8000 万台以上,是有史以来排名第 10 位的畅销主机。可索尼并非最后的赢家。如果说 PSP 这份成绩单是“取得了成功”,那卖掉 1 亿 5402 万台,差点掀翻 PS2 主机王座的 NDS ,无疑是个怪物级别的对手。
是不是觉得这历史不太对?
没错,虽然全球市场卖不过老任,但在中国大陆的情况却截然相反:PSP 的流行程度异乎寻常,几乎成了掌机的代名词。可索尼好像并不太笑得出来,因为PSP本体和软件的销量……有些不成比例。有很多人买了PSP,却一个游戏都没下单。
PSP破解史:猫鼠游戏
如果能认出这只煎蛋,说明你是真的老了。
主机也好掌机也罢,一直都是前期亏钱卖硬件,再通过软件销量赚回来。如果主机被过早破解,销量暴涨却没人为游戏买单,那就要亏疯了。而 PSP 的历史,也是索尼和黑客之间斗智斗勇的历史。
说起 PSP 破解,有三个关键词绝对绕不过去:M33、蛋图、普罗米修斯。
早期 PSP 破解,主要依靠系统和游戏漏洞来进行。如果新系统找不到可用漏洞,那就想办法降回旧版。游戏也不能直接从记忆棒启动,要有正版盘引导才行。索尼还在新游戏内加入系统版本要求,低版本破解系统的玩家不得不依赖黑客团队,对新游戏逐个解除版本限制。
2006 年,黑客大神 Dark-AleX 弄出了 PSP 破解圈的核弹:2.71SE 自制系统。这个天才般的点子,一脚把 PSP 破解踹进了黄金年代:这两年索尼的系统防护,突然变得像纸一样脆弱不堪。黑客团队推出自制系统的速度,几乎能和官方补丁同步。
(现在还能找到当年的教学贴)
更夸张的是在这之后,售后刷机用的“神奇电池”制作方法流出,刷机破解一夜之间变得无比简单。屏幕大、能看听歌电影、破解之后游戏资源丰富,还能看电子书、玩模拟器、甚至用上 Java QQ ……一台更比 6 台强的 PSP ,迅速在中国大陆流行开来。
08 年 3 月,电玩巴士在中关村“偶遇”平井一夫。据说当天姨夫在e世界买了台 PSP ,还被店主当面破解好了才带走……不知道这跟后来的改进有无关联,但索尼后续的动作,的确给黑客制造了不小的麻烦。
(图片来自电玩巴士,当年那报道还能打开)
在这之后不久,索尼推出了硬件大改的 v3 主板,以及配置小幅变化的 PSP 3000 。不光废掉了之前的破解,也堵死了神奇电池刷机这条路。v3 主板在黑客面前坚持了大约 1 年时间,然后又一次栽在了图片漏洞上。自制系统继续平推,直到 PSP 生命周期终结。
这中间还有一起悲剧。借助《王国之心:梦中降生》的破解,A9VG 论坛大神 liquidzigong 和他的普罗米修斯固件迅速流行开来。但几个月后,为了维护正版销量, liquidzigong 决定不会第一时间放出《怪物猎人3 携带版》相关破解,而是要等到首周销量公布之后。
由于游戏热度过高,上了头的伸手党们纷纷开始攻击 liquidzigong ,更有人试图对他进行人肉搜索。最终导致 liquidzigong 宣布退出 PSP 破解届,并要求各组销毁此前用于汉化的破解版游戏和固件。
(这个帖子中的两项要求均未被遵循)
固件和游戏最终还是泄露了出来,可这段中国 PSP 破解圈子的辉煌历史,就这样迅速迎来了黯淡结局。
官方维修终止、v3完美破解……PSP迎来最后结局
在生命末期, PSP 推出了两个极端的改型。上市天价的 PSP GO ,和一个不太为人所知的超级廉价款,PSP E1000。前者由于售价太高,且不支持 UMD ,一开始饱受恶评。而后者则因为阉割掉了 WiFi 模块无法联机对战,并未掀起太多波澜。
(末期超廉价型号 E1000 )
接下来,整个 PSP 系统开始稳步走向终点:2011 年, PSP 收到 6.60 系统推送,并被迅速破解。PSV 也在这年发布, PSP 进入寿命倒计时。2014 年, PSP 彻底停产,在线商店关门大吉。同年 3 月 31 日,PSP-1000、2000 型号维修服务终止。
2015 年,索尼不知为何突然发布了 6.61 系统,但几乎没造成什么影响。之后在 2016 年情人节,开发者 Davee 放出 Infinity 固化破解杂交系统,除 PSP E1000 外均可使用。v3 主板在上市 8 年后,终于迎来可关机的完美破解。
2016 年 4 月 21 日,乙女向游戏《诸神的恶作剧 InFinite》发售,这是登陆 PSP 最后一款游戏。尽管在这之后,《剑、魔法与学院 3》曾试图在北美打破这个记录,但最终还是取消了计划,只上了 PSV 平台便草草收场。同年 8 月 1 日,PSP Go 维修服务终止。
直到今年 9 月 30 日,PSP-3000 系列官方维修服务宣告终止,一个时代正式落幕。但黑客还没有放弃努力。上个月 10 号,Davee 终于放出了支持 PSP E1000 的 Infinity2.0 系统。PSP 破解史,也同样划下完美句点。
你喜欢的游戏都还在:战神系列本来就是索尼的看家招牌,PS4 上的新作也备受玩家好评(虽然疯狂锻炼手速的 QTE 小游戏被砍了很可惜)。至于怪物猎人系列,在卡普空反复叛教后已经网游化,不光 PS4 和 XBox , Steam 上也玩的到。
亲手发布了 PSP ,并为全球索粉贡献了一堆表情包的平井一夫先生,今年初宣布荣休。
那掌机战争呢?PSP 屹立不倒,NDS 系列销量碾压,但这里没有赢家。智能手机掀起的巨大浪潮,瞬间把整个掌机市场拍在了沙滩上。索尼曾对 PSP 寄予“ 21 世纪 Walkman ”的厚望,但最终夺走这个称号的,是乔布斯和他的 iPhone 。
历史的有趣,往往在于分岔之处。
2008 年,PSP 开始带有 Skype 网络电话服务,可以通过 WiFi 拨打网络电话。2011 年 3 月,索尼爱立信推出几乎复刻 PSP Go 外形的手机 Xperia PLAY ,这应该是已知最早的安卓游戏手机。而在 iPhone 3Gs 于 2009 年推出前,当时已经卖掉 5000 万台的 PSP ,可能一直是图形性能最强的手持消费电子产品。
索尼离那个统治世界的正确答案,曾经只差一步。
鸿蒙系统全面揭秘!腾讯开发工程师不吹不擂,带你深入剖析
作者:michalliu,腾讯 WXG 客户端开发工程师
华为鸿蒙OS有什么创新,是否自主研发完全开源,本文带你深入鸿蒙的世界。
一、初识鸿蒙
国内在计算机基础核心领域缺乏建树,一直没有自主知识产权的操作系统。之前又出过多起诸如汉芯,红芯浏览器等造假事件,犹如现实世界的“狼来了”,使国人对任何打着自主知识产权宣传的产品都会戴着放大镜去看,那么鸿蒙到底是不是个例外?
鸿蒙是个很泛的概念,鸿蒙不仅一个操作系统,还是一个生态。鸿蒙这个词在不同的场景下指代不同的东西。根据华为官方IDE DevEco Studio 的应用模板可以看出,目前鸿蒙支持的设备有手机,平板,电视,手表,汽车,以及相机等小家电等等,不同的技术栈开发的应用支持的设备种类也不同。其中Java类型的应用支持的设备类型最为丰富,JS类型的应用其次,C 应用支持的类型最少。
这些设备大体上可以分为嵌入式和非嵌入式两种。根据应用所需内存大小又可以分为L0-L5六个级别:
在嵌入式领域, 鸿蒙指是一款嵌入式操作系统,鸿蒙的核心为LiteOS,系统只能在配套的硬件(开发板)上运行,并非通用的操作系统,OpenHarmony是其对外开源的版本,在2020年9月在gitee上开源OpenHarmony 1.0,关于这款系统华为自身的文档比较欠缺,这里有较为详细的开发者文档。
在非嵌入式领域, 鸿蒙指的是一款叫鸿蒙的手机操作系统,最近网上热议的“此应用专为旧版鸿蒙打造”令人疑窦丛生。
因为截至目前鸿蒙只发布了一个版本,根本不存在所谓的旧版鸿蒙。由于鸿蒙的手机版操作系统并未开源,提示语又与android如此类似,不得不令人怀疑是字符串批量替换。那么事实真是字符串替换如此简单吗?下文将会予以分析。
总的来说,鸿蒙绝不仅仅指的是操作系统,华为的野心也绝不止于此,华为是要打造一个叫鸿蒙的生态,我们不排除未来会有鸿蒙SDK植入其它厂商的设备,使这些设备也具备运行鸿蒙应用的能力,甚至是运行在传统的Windows、Linux上的设备,那么这些设备也可以说是一个鸿蒙设备,是鸿蒙生态的一部分。
二、鸿蒙核心
经调研,我们认为鸿蒙生态的核心是以下四点:
1、多设备兼容
即开发出来的应用,可以覆盖多种类型的设备,屏蔽底层OS的差异,类似目前火热的Flutter所解决的问题。
2、卡片式应用
在多设备兼容的基础上带来一致的,高性能的交互体验。可以理解为跨设备,跨平台,跨网络的轻量Widget。
3、软总线
在以上两点的基础上,降低设备间互联互通的门槛。主要基于以下三点改进:
(1)设备间的发现和连接:从手动发现,进化成自发现:
(2)多设备互联后的组网技术:软总线组网-异构网络组网:
(3)多设备多协议间的高效传输技术:
4、通信安全
要实现设备间的互联互通,那么安全无疑是特别重要的环节。这里的问题是如何保证正确的人使用正确的设备,消费正确的数据。即要解决如下三个问题:
(1) 如何保证消费者对设备的鉴权是安全的,保证设备是原厂生产,没有被篡改的?(正确的设备)
(2) 如何保证消费者操作设备数据是安全的?(正确的人)
(3)如何保证消费者数据安全?(正确使用数据)
鸿蒙在系统和数据通信安全方面有较为完善的考虑。
三、系统层分析
基于鸿蒙已经开源的openharmony源码统计,openharmony包含C代码2KW行,C 500W行。
1、内核部分
鸿蒙宣传的微内核,并未说明是哪个鸿蒙,华为目前已经发布的内核包括:
1、Linux 面向手机 (L5级别设备)
2、LiteOS-a 面向有MMU的设备 (>=L1级别)
3、LiteOS-m 面向无MMU的嵌入式设备 (L0级别)
目前行业内对内核进行分类主要是:
微内核优点:
1、代码量小,可以形式化验证,可以减少bug量,几乎可以0 bug,另外更加方便移植。
2、各个系统组件或者服务如果存在问题可以直接重启服务,减少核心组件异常对整个系统的破坏,并按需组织系统服务。
3、各组件可以按需加载(现在宏内核也支持模块动态加载卸载)。
4、可以规避GPL协议。
微内核缺点:
1、所有资源获取都需要通过IPC,IPC又必须陷入内核,所以会导致频繁的陷入内核,或者多次拷贝,导致性能下降。当然IPC通信效率随着深入研究与技术发展逐步提高。
2、对于中断响应,需要映射到用户空间再处理,效率较低。
3、大量使用某些系统服务的时候,会导致进程上下文切换,增加系统负担。
而目前开源出来的鸿蒙代码 LiteOS-a按照业界对内核分类依旧是宏内核。至于华为是否存在微内核但没有开源,还是在实现鸿蒙过程中,又重新选择了宏内核,我们不得而知。
1.1 LiteOS-M
LiteOS-M和HW以前开源的Lite OS基本相同,进行部分结构性调整,当前只适用于cortex-m3、cortex-m4、cortex-m7、risc-v芯片架构,是纯粹的RTOS系统,通过KAL与上层服务匹配。
1.2 LiteOS-A
LiteOS-A是HW基于LiteOS进行演进的,进行 多进程,多核,虚拟内存,IPC等重新封装,尽量类似于Linux,但是尽量简化内核实现。OpenHarmony LiteOS-A内核架构图:
LiteOS-A是HW基于LiteOS进行演进的,进行 多进程,多核,虚拟内存,IPC等重新封装,尽量类似于Linux,但是尽量简化内核实现。
LiteOS-A相对于纯粹的RTOS增强关键特性简介:多进程: 基于task进行封装,较为简单的进程与线程调度(支持时间片和FIFO调度);
多核: 全局链表、所有CPU共享,支持空闲轮询调度(不支持负载均衡),可支持亲和设置,可绑定核运行。
虚拟内存:内核静态映射,静态映射提升虚实转换效率,最有区间分布(0-1G用户空间,1-4G内核空间,减少用户态进程页表项),用户态通过缺页异常按需获取内存。动态链接: 按需加载,多应用共享代码段,加载最小单元为页,符号绑定,支持立即和延时绑定,加载地址随机化,进程代码段,数据段,堆栈段地址随机化。并且运行标准ELF文件。
进程通信(IPC): 支持标准的posix进程间通信,如Mqueue,pipe,fifo.signal。同时添加了Lite IPC(类似与Android binder但是简单得多),ROM和RAM占用不超过30K,达到轻量,基于白名单控制的服务访问权限,提升安全,通过内存映射实现单次拷贝,实现高效。
系统调用: 通过MUSL实现系统调用支持syscall API和VDSO API。VDSO是减少系统调用开销的方式,Linux也支持。保证服务与内核分离。并且服务和应用不能随意访问内核。
权限管理: 进程粒度的权限划分与管理,完成DAC访问控制,以进程UID的配置,灵活划分文件资源归属与管控,提供UGO(user,group,other)的权限分配,满足基本的文件共享需求和Posix规范。
虚拟文件系统: VFS管理根目录,挂载点内目录有FS管理。通过BCache和PCache提升文件系统读写速度。
POSIX标准库: 基于Musl C的posix标准库,当前支持1000 的标准Posix接口。用户态使用全量Musl,C 使用libC ,内核使用部分Musl。
以上特性都基本上基于Linux的简化版本,保持内核小型化,并且尽量拥有Linux的功能特性。
1.3 Linux
鸿蒙OS Linux内核基于Linux 4.19版本内核,添加如下功能。
CVE补丁
补丁所涉及的CVE(Common Vulnerabilities and Exposures)安全漏洞是通过NVD (https://nvd.nist.gov/)官方机构收集,且补丁已经进入LTS 4.19.y分支或主线,主要涉及存储(btrfs/scsi/)、网络(net/bpf/mwifiex) 、驱动(xen/nfc),对应CVE列表参考commit信息中CVE字段信息。
OpenHarmony特性
HDF驱动、binder ipc转发功能等特性支持。
特定芯片架构驱动补丁(比如Hi3516DV300)
vendor厂商提供的特定芯片架构驱动代码:
hisi_linux-4.19_hos_l2.patch: 在Hi3516DV300芯片上支持arm架构的内核启动(DTS等)及对应的drm/mmc等驱动的支持。
2、子系统
openharmony LiteOS-A包含如下子系统:
系统基本能力子系统集:为分布式应用在多设备上的运行、调度、迁移等操作提供了基础能力,由分布式软总线、分布式数据管理、分布式任务调度、公共基础库、多模输入、图形、安全、AI等子系统组成。
基础软件服务子系统集:提供公共的、通用的软件服务,由事件通知、电话、多媒体、DFX(Design For X) 等子系统组成。
增强软件服务子系统集:提供针对不同设备的、差异化的能力增强型软件服务,由智慧屏专有业务、穿戴专有业务、IoT专有业务等子系统组成。
硬件服务子系统集:提供硬件服务,由位置服务、生物特征识别、穿戴专有硬件服务、IoT专有硬件服务等子系统组成。
根据不同设备形态的部署环境,基础软件服务子系统集、增强软件服务子系统集、硬件服务子系统集内部可以按子系统粒度裁剪,每个子系统内部又可以按功能粒度裁剪。
3、多内核支持
如上图所示,对于鸿蒙OS,其可以支持各种内核(目前支持Liteos-m,LiteOS-a,Linux)。其通过KAL层对上层提供统一的API接口能力。
我们可以清楚的看到KAL 支持统一是通过支持POSIX和CMSIS(针对arm Cotex-m 的抽象,做到在RTOS层面的尽量统一)对底层内核进行统一封装。做到基于上层API的程序可以在相应的CPU下编译通用,强调只能编译通用。
其中兼容POSIX的库是Musl-libc。该库是一个轻量级的C标准库,设计作为GNU C library (glibc)、 uClibc或Android Bionic的替代用于嵌入式操作系统和移动设备。它遵循POSIX 2008规格和 C99 标准,采用MIT许可证授权,使用Musl的Linux发行版和项目包括sabotage,bootstrap-linux,LightCube OS等等,然后通过HDF来统一驱动模块的编写调试过程。以此来兼容驱动设备。
POSIX表示可移植操作系统接口(Portable Operating System Interface of UNIX,缩写为 POSIX ),POSIX标准定义了操作系统应该为应用程序提供的接口标准。POSIX标准意在期望获得源代码级别的软件可移植性。换句话说,为一个POSIX兼容的操作系统编写的程序,应该可以在任何其它的POSIX操作系统(即使是来自另一个厂商)上编译执行。
CMSIS(Cortex Microcontroller Software Interface Standard)标准,它是ARM同各个微控制器供应商、工具供应商和软件解决方案一起开发的Cortex微控制器软件接口标准。它使得微控制器和软件供应商可以使用一致的软件结构来开发Cortex微控制器的软件。
CMSIS-RTOS是CMSIS的一部分,它本身是一种API规范,各厂商可以基于CMSIS-RTOS构建自己的实时操作系统(RTOS)。由于基于CMSIS-RTOS的API是标准化的,所以基于这些API开发的应用软件,不需要进行额外的移植开发工作,就可跑在任何支持CMSIS-RTOS的OS上。随着基于CMSIS-RTOS的中间件越来越多,支持CMSIS-RTOS后的OS也会因此获得更多的中间件。
4、HDF驱动架构
OpenHarmony驱动主要部署在内核态,当前主要采用静态链接方式,随内核子系统编译和系统镜像打包。
驱动框架交互流程
如上图所示,发布设备服务,即在VFS创建固定的目录或者设备节点,并且通过HDI进行抽象。
下列是相关系统的适配层,让相应的内核支持HDF能力。然后驱动开发工程师通过 drivers_framework 提供的相关框架能力,编写HDF支持的各种驱动,所以HDF统一驱动,是建立在对各种内核集成的HDF 内核支持驱动作为转换层。所以如果有新的内核需要适配,那么khdf需要根据相应的内核,进行移植,具有较大工作量。
相关源码目录是:
下图是HDF-Framework层。用于支持HDF统一驱动的开发,加载生效或者卸载。
通过代码中的uhdf/uhdf2可以看到,鸿蒙OS也在尝试将部分驱动放入用户空间,也就是向微内核(或者混合内核)方向演进。但如果是使用Linux内核,通常也可以使用标准的Linux内核驱动模型编写驱动。只是不方便移植到其他的鸿蒙非Linux内核的设备。不过不同的设备,其CPU与外设可能并不相同,分别编写也可能。
四、软总线分析
鸿蒙提供的标准软件总线框架图:
主要代码目录如下图,lite和standard有一定差异。针对lite设备,只有发现,认证传输。
针对标准系统,则添加了组网,并且以client(SDK目录) Server(core目录)的方式设计。
现在开源出来的openharmony方案总体约束为在同一局域网下进行软总线互通。目前开源出来的还是TCP/IP协议建立的局域网。鸿蒙发布会描述的极简协议统一层,我们并没有看到。
软总线的时序图如下,Module可以看成分布式调度服务等,即其他使用软总线的模块。
对于pubulicService 对服务进行发布,实际同时对 软总线进行初始化。(前提是WiFi已经接入了WiFi的局域网)
传输在上面的publicService过程中创建的会话服务 CreateSessionServer()就是后续进行基于session会话服务的基础。调用者并不需要关心IP等,只需要使用创建的sessionID 进行通信即可。
g_sessionMgr->serverListenerMap[i] 用于存储session。SessionListenerMap结构中,最重要的是listener成员:onSessionOpened,是在会话创建时被回调的函数。
onSessionClosed:是在会话结束时被回调的函数。
onBytesReceived:是会话的数据到达的回调函数,注册的模块可以通过这个函数接收会话的报文,按照自己的格式进行解析,并执行会话要求的动作。例如:在分布式调度模块中,接收的数据解析后,可能是START_FA的命令。
相关的代码:
在StartBus()函数会调用StartSession()函数创建基于TCP的socket的会话管理服务。
循环监听服务来连接,数据传输。
简单总结,就是软总线的传输,是基于COAP发布服务,等待超级终端通过softbus的session进行传输。当client要访问某个设备(可以是远程,可以是本地)的服务,首行连接远程服务的session服务器,并发送数据。远程的session服务通过onBytesRecived接收到数据,并回调给module。而是用module的目的。发送数据调用SendBytes,就可以基于sessionID发送。
这个过程中,module也好,还是远程client的应用也好,都不需要知道服务在哪个地方,有软件总线进行处理即可,目前服务的发布只支持WiFi下的COAP。
在代码中可以看到,未来支持的软总线设备有BLE,COAP,USB三种类型。
我们推测软件总线之下应该还有一个针对复杂设备支持多层连接的适配层,以便屏蔽底层差异(当前只开源了WiFi和BT),包括支持上述设备的组网,路由以便构建一张局域网。根据当前的开源代码来看,主要还是基于wifi的局域网连接,其他形式自组网还未看到,但华为在通信这块有很深的功底,我们这里相信这个目标可以达成。
基于目前公开的信息,软总线架构推测如下图:
其中底层连接协议包括以太网、红外线、4G/5G/WiFi、BT、NFC等各种通信能力。目前NFC主要用于华为Card的认证,协助多设备之间的认证。
五、应用层分析
我们分别编写了鸿蒙的JS及Java应用,结合开放出来的部分源码及文档,对App安装包进行了简单的逆向分析。
1、开发环境
官方IDE DevEco Studio是基于开源的intellij的改造,能够用于本地调试的模拟器只支持JS应用。Java应用截止目前只支持远程模拟器(所谓分布式模拟器)不支持本地模拟器。运行远程模拟器都需要账号密码登录,账号密码需要注册华为ID并实名认证,而实名认证需要上传身份证照片或者银行卡资料,远程调试由于网络和资源分配原因并不流畅,流畅度和画质方面不尽人意,开发体验有点儿糟糕。
当然如果有真机,也可以使用真机进行开发调试,但华为这里又设了两道门槛,开发鸿蒙应用需要双重签名认证,除了应用本身的签名,还要对应用工程进行签名。这两个签名都需要在鸿蒙开发者网站上注册,生成相应证书后方可安装到真机,步骤相当繁琐。笔者搞这个签名走各种注册流程前后耗时一小时,对开发者不是很友好,好在配置完成后,后续可以直接使用,算是一次性劳动。
从目前的应用开发流程上看,以后开发鸿蒙应用有可能会对签名服务进行收费,笔者不禁回想起了诺基亚,摩托罗拉时代,J2ME应用证书签名外包给第三方公司,一个应用签名收费2000元否则无法安装到用户手机,搞死生态的事情。生态还没起来,应用开发流程搞的如此复杂,希望华为借鉴这个历史教训。
2、应用框架
鸿蒙应用UI框架有两套,支持Java、JS,IDE里有默认的模板。这两套框架的区别是,Java框架只支持鸿蒙Android系统,JS应用既支持鸿蒙Android系统,也支持鸿蒙嵌入式系统。鸿蒙JS应用在鸿蒙Android上是套了个Android应用的壳,这个壳会构建一个类似小程序的渲染环境,转换为Android的原生控件渲染,下文有展开分析。JS应用相比Java应用,在排版能力,扩展性,兼容性方面存在一定的局限性,更适合做信息展示类的应用。
对应的也有,Java和JS两套SDK,鸿蒙系统提供的名为Ability的应用框架也分别有Java和JS的实现。应用支持哪些设备,可以在应用的config.json中声明。
3、应用格式
无论是js应用还是java应用,代码最终编译出来包均为hap后缀,这个hap是未经hack的zip格式,可以使用标准的zip解压工具进行解压。
具体hap包的具体安装使用上,SDK提供命令行工具 hdc:
hdc shell am force-stop com.example.myapplicationhdc shell bm uninstall com.example.myapplicationhdc file send ~/DevEcoStudioProjects/MyApplication/entry/build/outputs/hap/debug/entry-debug-unsigned.hap /sdcard/entry-debug-unsigned.haphdc shell bm install -p /sdcard/hdc shell rm -rf /sdcard/xxxhdc shell am start -n "com.example.myapplication/com.example.myapplication.MainAbilityShellActivity" -Dhdc app install xxx.hap
3.1、Java应用
java应用在开发时依赖以下SDK包,只能用来编译代码,SDK反编译看不到源码,也未开源。
根据文件命名,对其功能推测如下:
Java应用解压后的产物如下:
这些文件的作用如下:
Java应用起来后用MainAbilityShellActivity承载,根据反编译后的壳代码分析,主要由HarmonyApplication完成对ability应用运行环境的初始化。
Java应用布局文件及显示效果如下图:
dump出UI的绘制方式(adb shell uiautomator dump),可以看到鸿蒙虽然定义了一套应用开发的DSL,但绘制部分还是用Android的UI控件来承载,非自绘UI。
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><hierarchy rotation="0"> <node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="com.michalliu.myapplication" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][1176,2328]"> <node index="0" text="" resource-id="android:id/decor_content_parent" class="android.view.ViewGroup" package="com.michalliu.myapplication" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][1176,2328]"> <node index="0" text="" resource-id="android:id/action_bar_container" class="android.widget.FrameLayout" package="com.michalliu.myapplication" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,72][1176,240]"> <node index="0" text="" resource-id="android:id/action_bar" class="android.view.ViewGroup" package="com.michalliu.myapplication" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,72][1176,240]"> <node index="0" text="entry_MainAbility" resource-id="" class="android.widget.TextView" package="com.michalliu.myapplication" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[48,115][528,196]" /></node> </node> <node index="1" text="" resource-id="android:id/content" class="android.widget.FrameLayout" package="com.michalliu.myapplication" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,240][1176,2328]"> <node index="0" text="" resource-id="" class="android.view.ViewGroup" package="com.michalliu.myapplication" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,240][1176,2328]"> <node index="0" text="你好,世界" resource-id="" class="android.widget.TextView" package="com.michalliu.myapplication" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[288,1160][888,1320]" /> <node index="1" text="javaApp" resource-id="" class="android.widget.TextView" package="com.michalliu.myapplication" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[366,1320][809,1480]" /></node> </node> </node> <node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View" package="com.michalliu.myapplication" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][1176,72]" /></node></hierarchy>
由此可以看出,鸿蒙Android版要脱离Android体系难度还比较高,毕竟核心的UI部分非自绘。
Java应用的运行环境示意图:
我们理解鸿蒙Android从设计上更类似QT跟Windows的关系,可以理解为在Android操作系统的基础上搭了一套自己的应用程序框架。
目前鸿蒙是跟Android深度绑定的,鸿蒙切换操作系统的可能性不是完全没有,但成本相当高,应该说鸿蒙Android的这个设计思路是既然摆脱不了安卓,基于这个前提,那么就充分利用它。
3.2、Js应用
从目前已经开源出来的部分上来看基于js开发的应用是一种类似小程序的开发方式,html,js,css首先会编译成jsbundle(编译工具本身未开源),jsbundle的执行不同的鸿蒙系统上有所区别。
Js应用在鸿蒙嵌入式系统上执行分析
经过对openharmony代码分析,在openharmony里Js应用是以自绘的方式渲染,支持的UI组件看起来还比较完善(从源码里看绘制部分似乎参考了部分flutter代码),使用三星的Jerry Js引擎,猜测是挖的三星的人?因为这个Js引擎实在太小众,Google V8他不香吗?
UI组件框架在 ace_engine_lite 里,从开源的代码我们看出支持的UI组件还比较丰富,除了常规的控件,还包含列表,动画等复杂控件的实现。
ace_engine_lite 负责维护UI组件的生命周期,事件通信,数据更新等,是逻辑层
UI组件的显示层在 graphic_ui 工程中,例如下图为UIButton绘制的实现:
目前这个自绘的工程只有嵌入式的的实现,没有Android对应的实现。
实际在Android工程上,鸿蒙走的并不是自绘的方案,而是类似ReactNative的控件转换,ReactNative采用的是React的语法,而鸿蒙Android采用的是Vue的语法,从国内的开发者生态上来看,这是个正确的选择。
鸿蒙的这个用C 实现类VUE语法,在嵌入式上自绘,Android上控件转换的Js跨平台渲染框架属于原创,可惜的是鸿蒙Android这块并未开源,不能深入研究。
Js应用在鸿蒙Android上执行分析
Js应用在鸿蒙Android上会转换成Android的UI控件,Js应用解压后的产物如下:
这些文件的作用如下:
对于Js应用来说核心逻辑由ohos.aafwk.ace.ability.AceAbility完成jsbundle的加载和运行工作。
(注意:虽然java应用和js应用在解压后目录结构似乎差不多,文件命名也差不多,但其工作原理完全不同。在Java应用里class.dex已经是鸿蒙应用的真正可执行代码。在js应用里class.dex还是一个壳,这个壳用于打造执行Js应用的运行环境,真正的业务逻辑在app.js里。)
js应用布局文件及显示效果:
dump出UI的绘制方式,可以看到Js应用的UI绘制,在鸿蒙Android上是用Android的UI控件来承载,非自绘UI。
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><hierarchy rotation="0"> <node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="com.example.myapplicationjs" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][1176,2328]"> <node index="0" text="" resource-id="android:id/decor_content_parent" class="android.view.ViewGroup" package="com.example.myapplicationjs" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][1176,2328]"> <node index="0" text="" resource-id="android:id/action_bar_container" class="android.widget.FrameLayout" package="com.example.myapplicationjs" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,72][1176,240]"> <node index="0" text="" resource-id="android:id/action_bar" class="android.view.ViewGroup" package="com.example.myapplicationjs" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,72][1176,240]"> <node index="0" text="entry_MainAbility" resource-id="" class="android.widget.TextView" package="com.example.myapplicationjs" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[48,115][528,196]" /></node> </node> <node index="1" text="" resource-id="android:id/content" class="android.widget.FrameLayout" package="com.example.myapplicationjs" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,240][1176,2328]"> <node index="0" text="" resource-id="" class="android.view.ViewGroup" package="com.example.myapplicationjs" content-desc="" checkable="false" checked="false" clickable="true" enabled="true" focusable="true" focused="false" scrollable="true" long-clickable="true" password="false" selected="false" bounds="[0,240][1176,2328]"> <node index="0" text="您好 世界" resource-id="" class="android.widget.TextView" package="com.example.myapplicationjs" content-desc="" checkable="false" checked="false" clickable="true" enabled="true" focusable="true" focused="false" scrollable="true" long-clickable="true" password="false" selected="false" bounds="[331,1173][844,1332]" /> <node index="1" text="Js Application" resource-id="" class="android.widget.TextView" package="com.example.myapplicationjs" content-desc="" checkable="false" checked="false" clickable="true" enabled="true" focusable="true" focused="false" scrollable="true" long-clickable="true" password="false" selected="false" bounds="[301,1347][874,1452]" /></node> </node> </node> </node></hierarchy>
鸿蒙应用层在设计上,基于自己的DSL和应用运行框架,在嵌入式设备上以自绘的方式渲染,在鸿蒙Android上通过适配层转换为Android原生控件渲染。这样的设计优势是减轻了工作量,组件方面可以复用Android的生态,能力会更丰富,毕竟从零再打造一套完整且庞大的UI体系成本太高,体验还不一定有Android做的好,而劣势则是牺牲了可维护性,两套方案要各自独立维护,维护成本较高,另外还可能带来兼容性的问题。从openharmony源码上看,基于自绘方案并没有预留给Android的扩展接口,targetos仅包含linux和liteos两种,因为渲染层架构不同,未来的改成一致的可能性也较低。
六、总结
鸿蒙OS并不定位于对Windows、Android进行替代,而是剑指万物互联时代全场景、多终端的操作系统,与此相对应,鸿蒙OS(及大华为体系)所有的生态布局也将围绕万物互联展开。鸿蒙OS在完成细分场景的拓展与跑马圈地后,鸿蒙OS将完善华为AIoT生态,进一步在智慧城市、车联网(深化)、工业互联网三方面发力推进。
中长期来看,鸿蒙OS与华为“云 端”芯片形成强大合力,进军产业物联网。华为优质网络设备是IoT的连接基础,连接获得了大量数据,但只有通过智能分析才能够形成杀手级应用。华为已在云侧和端测拥有昇腾、鲲鹏、麒麟等芯片,具备强大算力,叠加鸿蒙OS高效、灵活的执行力,将培育大量高价值应用。基于近景和远景的生态蓝图,当前鸿蒙OS的发力抓手仍是以移动端为核心的HMS产业链。