网龙99u代码在哪输

网龙:布局下一个十年_小宗师专辑:日,网龙网络有限公司(股票代码:00777.HK)在福建省体育馆为自己举办了十岁生日盛宴。与中国网游产业共同成长的十年,这家企业坚持自主研发和全球化战略,打造了中国网游产业的“网龙模式”。但与腾讯、盛大、网易等第一梯队相比,网龙的个头还是偏小,在规模上有着不小的差距。据统计,2009年第一季度中国网络游戏市场收入规模达55.14亿元。排名前三的厂商中,盛大以10.8亿元收入占据19.6%的市场份额,位居市场第一位。腾讯市场收入为9.1亿元,以16.5%的市场份额排名第二。网易排名第三,以7.1亿元收入占据12.9%的市场份额。而网龙第一季度总营收为1.739亿元。面对急速变化的网游市场和行业本身,网龙如何布局自己的下一个十年呢?10月13日,网龙网络有限公司执行董事暨行政总裁刘路远接受了本刊记者的专访。网游产业进入新的拐点以十年为一个纪元,中国网游产业已是沧海桑田。十年前,网游作为一项舶来品登陆中国。从《石器时代》到《传奇》、《奇迹》,国外网游你方唱罢我登场,中国网游则大多以代理运营商的面目示人。五年前,国产网游从国外游戏手中夺回半壁江山,成为中国网游市场的主导力量。“到如今,整整十年了,我们发现网游产业进入了新的拐点。”刘路远分析,近年来,各家有实力的网游企业通过上市募集到资金之后,纷纷积蓄起强大的力量,在人才、市场等方面的争夺日趋激烈。业内人士分析,随着中国网络游戏产业的快速发展,在未来两年内,中国游戏从业人员缺口将是60万。市场本身也在发生急剧变化,经过几年来网游用户的激增,未来增速将可能放缓。另一方面,用户对网游产品的口味正变得越来越挑剔。刘路远表示,未来将是全方位的竞争,客户体验将被摆在第一位。“对于客户而言,已经不满足于有游戏玩,而是不断对比游戏,希望游戏的操作更为流畅、界面更为友好、安全性更有保障。如果产品不够好,用户都会毫不犹豫地抛弃你。整个行业被市场逼着更加成熟,迫使企业更注重细节,迫使企业放下身段去倾听用户的心声。”他说道。国内市场如此,海外市场的竞争也日趋激烈。越南等新兴市场国家是近年来中国网游企业主要开发的区域,但这些国家本土的网游企业也在同时快速成长。行业和市场的变化,推动整个产业进入了全面竞争的时代。在刘路远看来,全面竞争时代的到来,对企业的研发能力、产品把控、团队管理等诸多方面都提出了相当高的要求。“有挑战,可也蕴藏着很好的机会。以往,竞争并不激烈的情况下,网游产品可能不需要太好的品质,就可以像圈地一样先把用户拉过来。但随着市场本身的成熟,会推动企业拿出更好的产品和服务,推动企业练好内功,促使行业走上长期稳健发展之路。”刘路远介绍,网龙目前正在积极调整自己的角色,坚持既定的“自主研发和全球化”两大战略,保证庞大的团队在激烈的竞争面前做出快速正确的响应。做让人开心的企业回想创业时的筚路蓝缕,刘路远说道:“当时,我们的团队从零起步,没有什么经验,没有人知道这个行业要怎么做才是对的,完全靠摸着石头过河。”不过让用户获得开,£却是网龙一以贯之的,甚至网龙创业伊始放弃了代理这条捷径,选择了艰难异常的自主研发道路。据刘路远回忆,彼时企业只要取得国外已经运作经营成熟的游戏产品代理权,经营的风险是很小的。“但我们那时候就在考虑,买来之后怎么办?网游不是个买断的产品,也不是个卖断的产品,用户不是说今天买完,再也不和你打交道。用户玩得过程中,不断有新的需求,不断有新的想法。如果单纯取得代理权,数据库不是我们自己的,源代码不是我们自己的,我们凭什么去不断满足客户的需求?”他表示,任何一个行业都可以让人赚到钱,但能让人心情愉快开心的行业却不多。“我们一直觉得我们从事的是个伟大的行业,我们都有个梦想,希望通过自己的努力,让我们的产品给用户带去快乐,为此我们要做很多尝试。”他说道。 面对网游全面竞争时代的到来,网龙以客户体验至上精神为指导,做了积极响应。从2007年开始,网龙就成立了专门的市场调查团队,采用面谈、设计测试题、问卷、电话、数据库行为分析等各种方式与用户取得沟通,去了解客户需求。刘路远强调,网龙不是单纯地输出产品,而是希望通过与用户的沟通不断调整开发策略,让用户在玩游戏的过程中获得一种娱乐和放松。值得关注的是,网龙还创立了91文学平台、进军手机软件、涉足网页游戏和互联网软件,呈现出多元化发展的态势。当问及网龙是否亦怀抱盛大一样的梦想,成为线上综合娱乐公司时,刘路远回应,既然网龙的目标是让大家获得快乐,通过网游是条路,通过其他方式也不错。他表示,“网龙目前除了大型网络游戏外,还涉足手机软件、网页游戏等新兴项目,目前已取得一定程度的研发储备,相信这些项目将来能为网龙带来可观的利润。未来,网龙将同样关注新兴的互动娱乐项目,并发挥自身的研发优势。”他介绍,目前网龙还准备开发教育类产品,希望能将学习变得不那么枯燥严肃,真正做到“寓教于乐”。边打战边练兵动起来的网龙,将年定位为练兵年。刘路远表示,网龙这两年的工作主要是抓住机遇,加强团队,把产品线塑造得更好,夯实基础去面对未来更加激烈的竞争。迈出的第一步是树起招兵旗。经过多年的发展积累,我国越来越多的人才对网游产业产生了认同,这为网龙的扩张提供了有利的外部环境。2008年开始,全球爆发金融危机,各个行业的优秀人才开始流动起来,开启了网龙大规模扩军备战的序幕。根据网龙财报显示,截止日,网龙的研发团队已经达到1963人,而去年同期,仅为781人。一年内增加了1000多人,对网龙团队的管理能力提出了考验。为此,网龙一方面同步引进了很多高级管理人员,一方面用“师博带徒弟”的方式,大力增强团队管理能力。刘路远还透露,网龙内部还推行自身开发的ERP。EA等内部管理工具,实现了无纸化办公和信息化管理。但网龙也因此付出了相当的代价。据网龙财报显示,2009年上半年,网龙研发投入约为人民币0.88亿元,比2008年上半年增加约146.3%。此外,网龙第二季度营收环比下降6.3%、同比增长10.6%上半年净利6640万人民币,同比减少42.4%。面对外界的质疑声,刘路远表示。“我们目前正稳健地朝持续经营的目标前进,扎扎实实地打造自己的团队,而不是简单通过并购,把报表做漂亮。我们认为研发团队的扩张,使得网龙一两年后就会有实力的爆发。目前团队刚组建,需要时间上的磨合,新人需要去真正理解行业的特色规律,需要时间学习,但是我想这个时间不会太久,很快我们就可以拿出一份让人满意的答卷。”据他介绍,2009年其实已经是网龙的丰收年了,不仅陆续推出了五六个新产品,与迪斯尼公司合作的《梦幻迪士尼》、和周星驰合作的《长江7号》年底都将陆续进入测试期,还有不少新产品已经立项,在2011年还会有更多新产品与用户见面。“我们一边提升团队实力,一边不断推出我们的产品,目前网龙已经拥有了位列全国三甲的强大研发实力。”他说。伴大款扶兄弟2008年网易与九城激烈的“魔兽争夺战”,标志着纯代理模式正式退出了历史舞台。自主研发、合作研发、代理加研发三种网游发展模式开始三分天下。其中,网龙被业界视为举起了“合作研发”的大旗。除了自主研发,网龙还与国外巨头合作授权开发,实行业务外包,为自己的下一个十年构建了层次完善的研究体系。提及合作研发。刘路远回忆,这步棋是2003年网龙在参加E3大展(当前世界上最为盛大的电脑游戏与电视游戏商贸展示会)上埋下的。作为国内首家参加E3大展的网游企业,经过和全球同行的交流,网龙发现大家一些思路是不谋而合的,产生了很多合作点。自此,合作研发成为网龙身上不可抹去的烙印。携手育碧、迪士尼、EA等国际巨头,通过授权开发,网龙旗下《英雄无敌在线》、《梦幻迪斯尼》等产品纷纷上架。业内人士分析,近年来,随着国内网游企业研发能力的同步上升,网龙、网易等一批强调自主研发的网游企业与他们的产品开始被国际同行们关注。由于目前我国严禁外资介入网游运营,不少跨国文化企业希望能借助与国内网游企业合作的方式介入网游开发,巩固和扩大自身品牌在中国的影响力。作为中国第二大网络游戏出口商,“全球化”和“自主研发”是网龙的两大基本战略,与巨头合作,既可丰富开发题材,增强开发实力,也可借助巨头们的海外影响力进军海外市场。除了“伴大款”,网龙扶持了不少“小兄弟”,带动产业集群做大。按照区域来划分的话,刘路远将时下国内的网游企业分为北京、上海、广东和福建四大帮派。相比之其他三派,网龙所在的福建帮实力最为弱小,福建全省的产业密集度尚不如其他三地。这使得部分媒体曾质疑网龙偏居一隅,与整个产业大部队脱钩。“作为海西文化创意产业的龙头企业,我们要挑起大梁,带动产业集群共同发展。”刘路远说道,从月份,网龙便通过设立外包部,采用资金扶持和业务外包等手段来扶持业内中小企业的发展。据刘路远介绍,目前与网龙长期合作的团队将近200个,有过合作关系的团队则达到了700个,现在网龙每个月有200多万的业务与这些团队发生密切的关系。值得关注的是,今年11月份,由网龙公司投资10.58亿元建设的海西动漫创意之都将在长乐海滨投入使用。据了解,该中心规划用地面积5000多亩,分为动漫创意研发生产基地、亲水滨海主题乐园、动漫学院三部分。刘路远表示,希望能以这个园区为依托,把行业上下游、周边的企业都吸引过来,集聚几万名的优秀人才,一起圆海西创意产业崛起的梦想。网龙的下一个十年如何,我们拭目以待。提醒您本文地址:相关文章市场合作,请您联系:
品牌广告合作,请您联系:
企业创新合作,请您联系:
满足以下场景,获得更高通过率:
新融资求报道
新公司求报道
新产品求报道
创投新闻爆料
为你推送和解读最前沿、最有料的科技创投资讯
聚集15家顶级投资机构的专业互联网融资平台
聚集全球最优秀的创业者,项目融资率接近97%,领跑行业&p&优秀的程序员会告诉你打根基的重要性,会劝你在厚积薄发前要隐忍。&br&&/p&&p&优秀的码农会告诉你学啥底层、啥啥啥一拖就好了,学了python还要啥自行车啊,数据结构排序函数二分搜索这不都内置了吗?工作中永远用不到,学算法有啥用啊?成为高手有很多种方法汇编是个屁啊?&/p&&br&&br&&p&+++基础的分割线+++&/p&&br&&p&列举几个我认为比较重要的根基并附入门书&/p&&p&编程语言,《程序设计语言-实践之路》《concepts of programming languages》&/p&&p&计算机通用知识,《csapp》&/p&&p&算法、数据结构,《算法导论》&/p&&p&程序设计、结构,没有书推荐&/p&&p&软件工程,这个词大家理解不同,我以为,《人月》《代码大全》《the pragmatic programmer》《sicp》、讲测试讲重构的都是软件工程,其实上面设计模式也是软件工程,哈哈&/p&&br&&p&这些书,初时读来感觉全无作用,而且要读多次才能体会其中意味,所以叫它根基也是十分合适,你根基越深才能爬得越高嘛。&/p&&br&&br&&br&&p&+++方向的分割线+++&/p&&br&&p&啥是优秀程序员?&/p&&p&记者和很多网民说熊猫烧香作者是高手&/p&&p&公司里你出什么bug他都能告诉你原因用什么软件有问题他都能回答你的你就觉得是高手&/p&&p&有人说徒手做产品的全栈才是高手&/p&&p&各语言的作者都是高手&/p&&p&有不写代码,扔出一个restful论文的&/p&&p&还有人说高德纳是神,他如果是神,那他那些代码一定是在考验我们,嗯&/p&&p&。。。。&/p&&p&上面这些的确都算是高手,我琢磨着前两年被开掉的moto公司员工里肯定也有做功能机的高手和写廉价板驱动的高手&/p&&br&&p&你想自己选自己的方向还是被人忽悠方向?&/p&&p&我的想法是自己都尝试玩玩,然后做自己喜欢的方向。当然,程序员的生态金字塔是上面做工具、基础设施给下面人用来给普通人编程序,所以你选方向可以参考一下这个金字塔模型&/p&&br&&br&&br&&p&+++爬坑的分割线+++&br&&/p&&br&&p&方向定下,然后就是做事了,一大误区就是 【追求最好的东西】,于是非得弄清楚:&/p&&ul&&li&php是最好的语言吗?&br&&/li&&li&OpenGL比directx差吗?&br&&/li&&li&程序员要先学数学吗?&br&&/li&&li&最好的c语言书是谭浩强写的吗?&br&&/li&&li&放屁要先脱裤子吗?&br&&/li&&li&linux发行版那么多该选哪个?&br&&/li&&li&某大牛说IDE不如编辑器&br&&/li&&li&听说黑客都是用记事本写程序的&br&&/li&&li&C#是升调记号应该读csharp而java不应念 [加wa(轻声)]&br&&/li&&li&。。。&br&&/li&&/ul&&br&&p&如果你是一个*nix世界的玩家的话,你应该知道有一个jargon来上面的毛病,叫yak-shaving,我以前提过几次yak-shaving,但是很多人看不懂,它的字面意思是Any seemingly pointless activity which is actually necessary to solve a problem which solves a problem which, several levels of recursion later, solves the real problem you're working on.&/p&&p&但一般都引申其意使用它,我这里举例一下:&/p&&p&你本来要打开软件写一个helloworld,软件提示你升级,你点了升级,提示你xx库不够新,然后你更新xx库,提示你要升级yy驱动,然后你升级yy驱动,系统告诉你要编译这个驱动,你必须下载s.f版本的编译器和库,你更新编译器,系统说s.f版本编译器必须在e.n系统上运行,然后你就升级系统了,几个小时过去,你发现系统升级导致了几个软件损坏,然后你更新那些软件,去找解决问题的方法,不知不觉到了半夜,你累成了狗,却发现问题还有一大堆,而helloworld也没写成。。。。&/p&&br&&p&这些问题我都遇到过,我的建议是挑一本大牛说的书就是了,看会了其他也会了。当然,如果你不幸不认识大牛(都上知乎了只要会搜索这种事情不可能发生),或者单纯好奇——就像我当年那样的话,那就每种都试试,不过有的答案你自己知道就好,像是编辑器emacs比vim更好,写程序ide比编辑器更好这种话,你是不应该乱说出来的。&/p&&p&对了,像是不同范式的编程语言、不同的开发环境是应该尝试体验一下的,不过这种建议书上都写了,我这里说显得有些废话了。&/p&&br&&p&所以说,不能被无关的东西弄偏了目标,要专注,坚持。&/p&&p&等你学深了一门语言,就算是学另一们其他范式的语言也不会太难,你学会了opengl,dx也就看看就能写了。&/p&&br&&p&你看看武侠小说里,段誉就是一个傻逼,仗着有时发出有时发不出的脉冲波和绕圈圈就能快跑直线的bug技就加上一门佛学能独步武林最终迎娶了白富美,出任了CEO,走向了人生巅峰,乔峰永远是一招降龙十八掌,更夸张。而慕容复文武双才,基本精通天下武学,每天读书4时辰练功4时辰,论用功谁能和他比啊。。。可到了30多岁还是一事无成,pk连段誉这种新手都搞不过,最后被人抢了老婆,就是因为方向不对,而且太不专注了。&/p&&p&所以求多不如求专,深度到了,再花20%的时间去扩展一下广度即可。&/p&&br&&br&&br&&p&+++重要的分割线+++&/p&&br&&p&以上东西你都做好了,要花个2年时间的样子,对于学生来说,如果你有一个好的学校背景,人生可以就此扬帆起步了&/p&&p&但这不是终点,俗话说人靠衣装,美靠包装。包装是门学问,这里的包装不是让你西装领带亮皮鞋黑丝套裙白衬衫整一个营销狗hr的造型,是说专业技能上的包装。&/p&&br&&p&为什么这是最重要的部分呢?因为别人一般不和你说这么多,尤其是懂得包装的人,更不会传你这些不传之秘啦。。。。。&/p&&br&&p&&b&&u&包装自己的第一步是提高实力&/u&&/b&&/p&&p&没有实力的包装那是空中楼阁,只能靠每天日常搞外包的忽悠架构大数据云计算过活,明眼人也能看出来,所以纯属作秀,没有意义。&/p&&p&在某个领域(编译器、虚拟机、开发架构、前端。。。)成为专家(专家的定义嘛,,我的理解是能在简历里写精通)后,包装的实力就算具备了。&/p&&br&&p&&b&&u&包装的第二步是定位&/u&&/b&&/p&&p&提到美国会有一大堆人跳出来说是人类的希望民主的大救星,提到google就是最纯的技术公司不作恶、软件业的翘楚开发界的标杆、心美人美白莲花。。。哪怕你列举google卖假药、恶意打压yelp、挟持web标准等等等等这些事,他们也会说百度更差(咦这不5角钱常用的语句吗怎么被民主进步人士盗取了?。。。),可我根本没提到百度好吗。。。&/p&&p&这全是包装造成的,所以包装的巨大威力,以此可窥之。&/p&&br&&p&google是搜索引擎,百度难道也说自己是搜索引擎?不,百度说自己是最懂中文的搜索引擎。。。哈哈哈,你别笑,这的确很管用,就像google说自己不作恶是好女孩一样。&/p&&br&&p&程序员的包装定位,无非稀缺和独特这两点。物以稀为贵,稀缺就是要做到不可替代,这很好理解,比如你知道世界第一高峰是珠穆朗玛峰,如果没看过禅师精选集你很难知道第二高峰是乔戈里峰,但文青特别偏好乞力马扎罗山,不爬不跟你结婚,为啥?独特性嘛。。。我不跟你比高,我和你比文化底蕴,于是就赢了。&/p&&br&&p&由于你有实力,所以你应该尽量把自己的实力包装成稀缺属性,你是专家嘛。。然后你实力多,应该把独特的实力包装出来,避免和他人共同曝光,以免被人压在身下。&/p&&br&&p&我说一个我朋友包装自己的故事,他进公司接手了一个项目,已经是被隔壁组开发了3,4个月的一个软件,其实这软件2个月也能做好的,但是隔壁人忙而且也不上心,不熟悉这个技术,加上又不是自己的老板,所以做事拖沓了那么久才做好。他接手后一刻没闲,晚上带回家也做,做到半夜,10天做成,然后整个公司的人都知道他的名字了,他也就立稳脚跟了。&/p&&p&这个包装的主题是,技术实力强,开发速度快。&/p&&br&&p&&b&&u&包装的第三步是推广&/u&&/b&&/p&&p&推广就是让人知道你做得好,强化你的个人品牌,可以用博客、知乎、mailing-list、github等,通过写文章、参加线下聚会演讲、回答问题、帮助他人等方法。这个用好了是门学问,用不好就是装逼,不展开了。。。&/p&&p&记住不要匿名,匿名你基本啥也得不到&/p&&br&&p&有人明明技术实力强,但是由于没有包装好,或被埋没了才能,或被贴上了各种不应该有的标签,或被人偏见看待。比如 &a data-hash=&78e3b2ae1be4ab038a6e& href=&///people/78e3b2ae1be4ab038a6e& class=&member_mention& data-hovercard=&p$b$78e3b2ae1be4ab038a6e&&赵劼&/a& 的c#和 &a data-hash=&ecc0ec035f& href=&///people/ecc0ec035f& class=&member_mention& data-hovercard=&p$b$ecc0ec035f&&vczh&/a& 的微软标签&br&&/p&&p&有人明明实力一般,但是善于鼓动小白,包装得好,所以有一批忠实粉丝,这种人我都不太敢说名字了,呵呵。。&/p&&p&所以优秀的程序员应该善用包装啊&/p&&br&&br&&br&&p&+++结尾的分割线+++&/p&&br&&p&上面说了那么多,但是坚持做来需要不少推动力,有人能考上清华,但是也能在大学堕落,有人能取得成绩,但是也会固步自封。。&/p&&p&要想优秀,得有巨大的推动力,你为啥想成为优秀的程序员?你的推动力是什么?&/p&&br&&p&好比,我们说,嫖娼是有巨大道德压力、金钱压力和风险的事情,为啥知乎上那么多嫖客乐此不疲并努力给自己洗脑合理化这件事呢?因为在他们的眼中嫖娼是最有趣的事情、是不吃饭不睡觉也不能不做的事情、是不做就活着没劲的事,有了这种死也要死在床上的精神,还怕什么呢?&/p&&br&&p&&b&&u&这就是推动力&/u&&/b&&/p&
优秀的程序员会告诉你打根基的重要性,会劝你在厚积薄发前要隐忍。 优秀的码农会告诉你学啥底层、啥啥啥一拖就好了,学了python还要啥自行车啊,数据结构排序函数二分搜索这不都内置了吗?工作中永远用不到,学算法有啥用啊?成为高手有很多种方法汇编是个…
&img src=&/v2-d6ca68eecf329fe411e6_b.jpg& data-rawwidth=&1300& data-rawheight=&600& class=&origin_image zh-lightbox-thumb& width=&1300& data-original=&/v2-d6ca68eecf329fe411e6_r.jpg&&&blockquote&&i&面试官:“熟悉哪种语言”。应聘者:“JAVA”。&br&面试官:“知道什么叫类么”。应聘者:“我这人实在,工作努力,不知道什么叫累”。&br&面试官:“知道什么是包?”。应聘者:“我这人实在平常不带包也不用公司准备了”。&br&面试官:“知道什么是接口吗?”。应聘者:“我这个人工作认真。从来不找借口偷懒”。&br&面试官:“知道什么叫对象么?”。应聘者:“知道,不过我工作努力,上进心强,暂时还没有打算找对象。”。&/i&&/blockquote&&br&&br&&br&&br&&h2&&b&1.如何使用Cordova和VueJS构建Android应用程序&/b&&/h2&&img src=&/v2-a4c53f9c0_b.jpg& data-rawwidth=&666& data-rawheight=&300& class=&origin_image zh-lightbox-thumb& width=&666& data-original=&/v2-a4c53f9c0_r.jpg&&&p&我们无法为每个项目编写一个原生的Android应用程序。作为一名Web开发人员,我必须从头开始学习Android SDK,这太可怕了,但是,我可以制作一个网络应用程序并将其转换成Android应用程序&/p&&a href=&/?target=https%3A///how-to-build-an-android-app-using-cordova-and-vue-js/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&链接地址&i class=&icon-external&&&/i&&/a&&br&&br&&br&&br&&br&&h2&&b&2.REST 2.0 在此,它的名字叫 GraphQL&/b&&/h2&&img src=&/v2-e5d51faa9a7bdd708a2830_b.jpg& data-rawwidth=&666& data-rawheight=&300& class=&origin_image zh-lightbox-thumb& width=&666& data-original=&/v2-e5d51faa9a7bdd708a2830_r.jpg&&&p&GraphQL 是一种 API 查询语言。虽然它和 REST 完全不同,但是 GraphQL 可作为 REST 的代替品,提供一样的体验。对于一个有经验的开发者来说,它可作为一个非常强有力的工具。&/p&&a href=&/?target=https%3A//juejin.im/post/fe& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&链接地址&i class=&icon-external&&&/i&&/a&&br&&br&&br&&br&&br&&h2&&b&3.2017 春季最酷的 30 个 Android 库&/b&&/h2&&img src=&/v2-04ac3fce4f_b.jpg& data-rawwidth=&666& data-rawheight=&300& class=&origin_image zh-lightbox-thumb& width=&666& data-original=&/v2-04ac3fce4f_r.jpg&&&p&这里是 30 个我最喜欢的在 2017 年 3 月前新出现的 Android 库。其中一些并没有用于实际产品,但你使用它们可能会得到很多的乐趣。我希望你们喜欢这些库。&/p&&a href=&/?target=http%3A//www.oschina.net/translate/30-new-android-libraries-released-in-the-spring-of-2017& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&链接地址&i class=&icon-external&&&/i&&/a&&br&&br&&br&&br&&br&&h2&&b&4.快速了解内存管理&/b&&/h2&&img src=&/v2-f40e6e116b4d965d3caa6dd_b.jpg& data-rawwidth=&666& data-rawheight=&300& class=&origin_image zh-lightbox-thumb& width=&666& data-original=&/v2-f40e6e116b4d965d3caa6dd_r.jpg&&&p&您需要了解一些关于内存管理的内容,要理解为什么将ArrayBuffer和SharedArrayBuffer添加到JavaScript中。&/p&&a href=&/?target=https%3A//hacks.mozilla.org/2017/06/a-crash-course-in-memory-management/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&链接地址&i class=&icon-external&&&/i&&/a&&br&&br&&br&&br&&br&&h2&&b&5.JavaScript之跟着 underscore 学节流&/b&&/h2&&img src=&/v2-a9d5de486ea110e273ca2afaaa644740_b.jpg& data-rawwidth=&666& data-rawheight=&300& class=&origin_image zh-lightbox-thumb& width=&666& data-original=&/v2-a9d5de486ea110e273ca2afaaa644740_r.jpg&&&p&节流的原理很简单:如果你持续触发事件,每隔一段时间,只执行一次事件。&br&根据首次是否执行以及结束后是否执行,效果有所不同,实现的方式也有所不同。我们用 leading 代表首次是否执行,trailing 代表结束后是否再执行一次。&br&关于节流的实现,有两种主流的实现方式,一种是使用时间戳,一种是设置定时器。&/p&&a href=&/?target=https%3A///a/1691& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&链接地址&i class=&icon-external&&&/i&&/a&&br&&br&&br&&br&&br&&h2&&b&6.2017年CSS终极调查结果&/b&&/h2&&img src=&/v2-2fdaffe9f0_b.jpg& data-rawwidth=&666& data-rawheight=&300& class=&origin_image zh-lightbox-thumb& width=&666& data-original=&/v2-2fdaffe9f0_r.jpg&&&p&一份关于css的调查报告,在差不多6个星期的时间里,1600多人参与填写了问卷,现在向你展示结果和一些反馈&/p&&a href=&/?target=https%3A///results-ultimate-css-survey-2017/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&链接地址&i class=&icon-external&&&/i&&/a&&br&&br&&br&&br&&br&&h2&&b&7.前端与SQL&/b&&/h2&&img src=&/v2-0b72ade33ae4bf8c349eea_b.jpg& data-rawwidth=&666& data-rawheight=&300& class=&origin_image zh-lightbox-thumb& width=&666& data-original=&/v2-0b72ade33ae4bf8c349eea_r.jpg&&&p&本篇将介绍前端本地存储里的Web SQL和IndexedDB,通过一个案例介绍SQL的一些概念。&/p&&a href=&/p/& class=&internal&&链接地址&/a&&br&&br&&br&&br&&br&&h2&&b&推荐阅读&/b&&/h2&&p&&a href=&/p/& class=&internal&&极乐技术周报(第十三期)&/a& | &a href=&/p/& class=&internal&&极乐技术周报(第十二期)&/a& | &a href=&/p/& class=&internal&&极乐技术周报(第&/a&&a href=&/p/& class=&internal&&十&/a&一&a href=&/p/& class=&internal&&期)&/a&&/p&
面试官:“熟悉哪种语言”。应聘者:“JAVA”。 面试官:“知道什么叫类么”。应聘者:“我这人实在,工作努力,不知道什么叫累”。 面试官:“知道什么是包?”。应聘者:“我这人实在平常不带包也不用公司准备了”。 面试官:“知道什么是接口吗?”。应…
&p&搬运一下自己博客的文章: &a href=&///?target=http%3A//imzlp.me/posts/15272/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&main原型考证及程序终止行为&i class=&icon-external&&&/i&&/a&&/p&&br&&p&在C和C++中流传着很多版本的main函数声明,不同的书里也有不同的写法。今天我从几种标准(C89/99/11以及C++98/03/11/14)的角度来寻找一下什么是“&b&标准行为&/b&”以及在主函数中return后发生了什么。
比较常见的是下面几种:&/p&&div class=&highlight&&&pre&&code class=&language-cpp&&&span class=&kt&&void&/span& &span class=&n&&main&/span&&span class=&p&&()&/span&
&span class=&n&&main&/span&&span class=&p&&()&/span&
&span class=&kt&&int&/span& &span class=&n&&main&/span&&span class=&p&&()&/span&
&span class=&kt&&int&/span& &span class=&n&&main&/span&&span class=&p&&(&/span&&span class=&kt&&void&/span&&span class=&p&&)&/span&
&span class=&kt&&int&/span& &span class=&n&&main&/span&&span class=&p&&(&/span&&span class=&kt&&int&/span& &span class=&n&&argc&/span&&span class=&p&&,&/span&&span class=&kt&&char&/span& &span class=&o&&*&/span&&span class=&n&&argv&/span&&span class=&p&&[])&/span&
&/code&&/pre&&/div&&p&&b&void main()&/b&&/p&&p&首先,从标准角度(所有版本)来说,void main()肯定是错的,没有任何标准(C89/99/11以及C++98/03/11/14)中允许过这种写法。&/p&&p&但是我在APUE里看到了一种把主函数写为void main()的原因,不知道是不是有人从这个角度说的然后就以讹传讹了。&/p&&blockquote&The problem is that these compilers don’t know that an exit from main is the same as a return. One way around these warnings, which become annoying after a while, is to use return instead of exit from main. But doing this prevents us from using the UNIX System’s grep utility to locate all calls to exit from a program. Another solution is to declare main as returning void, instead of int, and continue calling exit. This gets rid of the compiler warning but doesn’t look right (especially in a programming text), and can generate other compiler warnings, since the return type of main is supposed to be a signed integer.&/blockquote&&p&评论区 &a class=&member_mention& href=&///people/7daac46c75d7cac1e7d2& data-hash=&7daac46c75d7cac1e7d2& data-hovercard=&p$b$7daac46c75d7cac1e7d2&&@James Swineson&/a& 提到了另一种可能:&/p&&p& void main 的写法可能是从嵌入式来的……没有操作系统,入口点是硬件实现,返回任何东西都没意义 。&/p&&p&&b&main()&/b&&/p&&p&在K&R C与C89里,函数没有显式声明返回类型,则默认是int:&/p&&p&C89对函数定义的语法(Syntax)描述如下(注意&i&declaration-specifiers&/i&的&i&opt&/i&下标符号):&/p&&p&$$declaration specifiers&i&{opt}\hspace{2mm}declarator\hspace{2mm}declaration list&/i&{opt}\hspace{2mm}compound statement$$&/p&&p&C89中&i&declaration-specifiers&/i&在&i&Syntax&/i&上为:&/p&&ul&&li&storage-class-specifier&/li&&li&type-specifier&/li&&li&type-qualifier&/li&&/ul&&p&表明在C89中函数的return type可以省略。&/p&&p&K&R C里的描述如下:&/p&&blockquote&Various a minimal function is&/blockquote&&div class=&highlight&&&pre&&code class=&language-cpp&&&span class=&n&&dummy&/span&&span class=&p&&()&/span& &span class=&p&&{}&/span&
&/code&&/pre&&/div&&blockquote&which does nothing and returns nothing. A do-nothing function like this is sometimes useful as a place holder during program development. If the return type is omitted, int is assumed.&/blockquote&&p&所以说:&/p&&div class=&highlight&&&pre&&code class=&language-text&&func(){}
int func(){}
&/code&&/pre&&/div&&p&但是这种方式在C99之后就被废除掉了(注意&i&declaration-specifiers&/i&没有&i&opt&/i&下标了):&/p&&p&&i&[Math Processing Error]declaration.specifiersdeclaratordeclaration.listoptcompound.statement&/i&&/p&&p&综上,在C89中,函数的返回类型可以省略,但默认为int,即&/p&&blockquote&主函数声明main()隐式是int main()。&/blockquote&&p&&b&int main()&/b&&/p&&p&int main()和int main(void)在C语言中是有区别的:&/p&&div class=&highlight&&&pre&&code class=&language-text&&int main()
// 不等价于
int main(void)
&/code&&/pre&&/div&&p&在C语言中参数列表为空(即不提供参数列表也不为void),表示不提供参数数量和参数类型信息:&/p&&div class=&highlight&&&pre&&code class=&language-cpp&&&span class=&kt&&int&/span& &span class=&nf&&func&/span&&span class=&p&&(){&/span&
&span class=&n&&print&/span&&span class=&p&&(&/span&&span class=&s&&&func()&/span&&span class=&se&&\n&/span&&span class=&s&&&&/span&&span class=&p&&);&/span&
&span class=&k&&return&/span& &span class=&mi&&0&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&kt&&int&/span& &span class=&nf&&main&/span&&span class=&p&&(&/span&&span class=&kt&&void&/span&&span class=&p&&){&/span&
&span class=&n&&func&/span&&span class=&p&&(&/span&&span class=&mi&&1&/span&&span class=&p&&,&/span&&span class=&mi&&2&/span&&span class=&p&&,&/span&&span class=&mi&&3&/span&&span class=&p&&,&/span&&span class=&mi&&4&/span&&span class=&p&&);&/span&&span class=&c1&&// call func();&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&blockquote&The empty list in a function declarator that is not part of a definition of that function specifies that no information about the number or types of theparameters is supplied.&/blockquote&&p&&b&C99/11 Standard&/b&&/p&&p&在C99/11标准中,明确定义了对于标准的main函数的两个原型:&/p&&p&The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of &b&int&/b& and with &b&no parameters&/b&:&/p&&div class=&highlight&&&pre&&code class=&language-cpp&&&span class=&kt&&int&/span& &span class=&nf&&main&/span&&span class=&p&&(&/span&&span class=&kt&&void&/span&&span class=&p&&)&/span& &span class=&p&&{&/span& &span class=&cm&&/* ... */&/span& &span class=&p&&}&/span&
&/code&&/pre&&/div&&p&or with &b&two parameters&/b& (referred to here as &b&argc&/b& and &b&argv&/b&, though any names may be used, as they are local to the function in which they are declared):&/p&&div class=&highlight&&&pre&&code class=&language-cpp&&&span class=&kt&&int&/span& &span class=&nf&&main&/span&&span class=&p&&(&/span&&span class=&kt&&int&/span& &span class=&n&&argc&/span&&span class=&p&&,&/span& &span class=&kt&&char&/span& &span class=&o&&*&/span&&span class=&n&&argv&/span&&span class=&p&&[])&/span& &span class=&p&&{&/span& &span class=&cm&&/* ... */&/span& &span class=&p&&}&/span&
&/code&&/pre&&/div&&p&or in some other implementation-defined manner.
If they are declared, the parameters to the main function shall obey the following constraints:&/p&&ul&&li&The value of argc shall be nonnegative.&/li&&li&&b&argv[argc]&/b& shall be a null pointer.&/li&&li&If the value of argc is &b&greater than zero&/b&, the array members &b&argv[0]&/b& through &b&argv[argc-1]&/b& inclusive shall contain pointers to strings, which are given implementation-defined values by the host environment prior to program startup. The intent is to supply to the program information determined prior to program startup from elsewhere in the hosted environment. If the host environment is not capable of supplying strings with letters in both uppercase and lowercase, the implementation shall ensure that the strings are received in lowercase.&/li&&li&If the value of argc is &b&greater than zero&/b&, the string pointed to by &b&argv[0]&/b&
represe argv[0][0] shall be the null character if the program name is not available from the host environment. If the value of argc is greater than one, the strings pointed to by &b&argv[1]&/b& through &b&argv[argc-1]&/b&
represent the program parameters.&/li&&li&The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination.&/li&&/ul&&p&&b&C++ Standard&/b&&/p&&p&由于C和C++中对于函数参数列表的规则并不一致(C++中参数列表为空代表不接收任何参数)。所以C++中main的原型和ISO C也并不太一样:&/p&&ul&&li&a function of &b&()&/b& returning &b&int&/b& and&/li&&li&a function of (&b&int&/b&, &b&pointer to pointer to char&/b&) returning &b&int&/b&&/li&&/ul&&p&&b&main return value&/b&&/p&&p&main必须要有返回值的原因是:在C和C++中使用return-statement都是将return的值作为参数来调用exit/std::exit来终止程序。&/p&&blockquote&If status is zero or EXIT_SUCCESS, an implementation-defined form of the status successful termination is returned.&/blockquote&&p&&b&ISO C99/11:&/b&
If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main func&b&reaching the } that terminates the main function returns a value of 0.&/b& If the return type is not compatible with int, the termination status returned to the host environment is unspecified.&/p&&p&&b&ISO C++11/14:&/b&
A return statement in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling &b&std::exit&/b& with the return value as the argument. If control reaches the end of main without encountering a return statement, the effect is that of executing&/p&&div class=&highlight&&&pre&&code class=&language-text&&return 0;
&/code&&/pre&&/div&&p&&b&exit&/b&&/p&&div class=&highlight&&&pre&&code class=&language-cpp&&&span class=&cp&&#include &stdlib.h&/span&
&span class=&kt&&void&/span& &span class=&nf&&exit&/span&&span class=&p&&(&/span&&span class=&kt&&int&/span& &span class=&n&&status&/span&&span class=&p&&);&/span&
&/code&&/pre&&/div&&p&The &b&exit&/b& function causes normal program termination to occur. If more than one call to the &b&exit&/b& function is executed by a program, the behavior is undefined.&/p&&ul&&li&First, all functions registered by the &b&atexit&/b& function are called, in the reverse order of their registration,except that a function is called after any previously registered functions that had already been called at the time it was registered. If, during the call to any such function, a call to the &b&longjmp&/b& function is made that would terminate the call to the registered function, the behavior is undefined.&/li&&li&Next, all open streams with unwritten buffered data are flushed, all open streams are closed, and all files created by the &b&tmpfile&/b& function are removed.&/li&&li&Finally, control is returned to the host environment. If the value of &b&status&/b& is &b&zero&/b& or &b&EXIT_SUCCESS&/b&, an implementation-defined form of the status &i&successful termination&/i& is returned. If the value of &b&status&/b& is &b&EXIT_FAILURE&/b&, an implementation-defined form of the status &i&unsuccessful termination&/i& is returned. Otherwise the status returned is implementation-defined.&/li&&li&Next, all open streams with unwritten buffered data are flushed, all open streams are closed, and all files created by the tmpfile function are removed.&/li&&li&Finally, control is returned to the host environment. If the value of status is zero or EXIT_SUCCESS, an implementation-defined form of the status successful termination is returned. If the value of status is EXIT_FAILURE, an implementation-defined form of the status unsuccessful termination is returned. Otherwise the status returned is implementation-defined., an implementation-defined form of the status unsuccessful termination is returned. Otherwise the status returned is implementation-defined.&/li&&/ul&&p&&b&The exit function cannot return to its caller.&/b&&/p&&p&&b&_Exit&/b&&/p&&div class=&highlight&&&pre&&code class=&language-text&&#include &stdlib.h&
void _Exit(int status);
&/code&&/pre&&/div&&p&The _Exit function causes normal program termination to occur and control to be returned to the host environment. No functions registered by the atexit function or signal handlers registered by the signal function are called. The status returned to the host environment is determined in the same way as for the exit function (7.20.4.3).Whether open streams with unwritten buffered data are flushed, open streams are closed,or temporary files are removed is implementation-defined.
The _Exit function cannot return to its caller.&/p&&p&&a href=&///?target=http%3A//1.z0./blog-images/others/StartAndterminatesACProgram.png& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&1.z0.&/span&&span class=&invisible&&/blog-images/others/StartAndterminatesACProgram.png&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&
搬运一下自己博客的文章:
在C和C++中流传着很多版本的main函数声明,不同的书里也有不同的写法。今天我从几种标准(C89/99/11以及C++98/03/11/14)的角度来寻找一下什么是“标准行为”以及在主函数中return后发生了什么。
&img src=&/v2-eb24dbad282d6f1fda047_b.jpg& data-rawwidth=&850& data-rawheight=&512& class=&origin_image zh-lightbox-thumb& width=&850& data-original=&/v2-eb24dbad282d6f1fda047_r.jpg&&&h2&0x00 前言&/h2&&p&在很长一段时间里,Unity项目的开发者的优化指南上基本都会有一条关于使用GetComponent方法获取组件的条目(例如14年我的这篇博客&a href=&/?target=http%3A///84323/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《深入浅出聊Unity3D项目优化:从Draw Calls到GC》&i class=&icon-external&&&/i&&/a&)。有时候还会发展为连一些Unity内部对象的属性访问器都要小心使用的注意事项,记得曾经有一段时间我们的项目组也会严格要求把例如transform、gameobject之类的属性访问器进行缓存使用。这其中的确有一些措施是有道理的,但很多朋友却也是知其然而不知其所以然,朦胧之间似乎有一个印象,进而成为习惯。那么本文就来聊聊Unity优化这个题目中偶尔会被误解的内容吧。&/p&&br&&br&&h2&0x01 来自官方的建议&/h2&&p&本文主要是关于Unity脚本优化的,而脚本和引擎打交道的一个常见情景便是使用GetComponent之类的方法, 接触过Unity的朋友大都知道要将GetComponent的结果进行缓存使用。不过很多人的理由是:&/p&&blockquote&&p&使用GetComponent会造成GC,从而影响效率。&/p&&/blockquote&&p&所以从Unity官方的手册来寻找关于GetCompnent的线索是最好的途径。的确,2011年的3.5.3版本的官方手册就已经建议减少使用GetCompnent方法来获取组件了,同时建议我们使用变量缓存获取的组件。&/p&&blockquote&&p&Reduce GetComponent Calls&br& Using GetComponent or built-in component accessors can have a noticeable overhead. You can avoid this by getting a reference to the component once and assigning it to a variable (sometimes referred to as &caching& the reference).&/p&&/blockquote&&p&但是,我们可以发现手册上只说了频繁的调用GetComponent会导致CPU的开销增加,但是并没有提到GC的问题。所以,为了验证GetComponent到底会导致哪些性能上的问题,我们可以做几个小测试。&/p&&br&&br&&h2&0x02 和GC无关的性能优化&/h2&&p&众所周知,GetComponent有三个重载版本,分别是:&/p&&ul&&li&GetComponent()&/li&&li&GetComponent(typeof(T))&/li&&li&GetComponent(string)&/li&&/ul&&p&所以,测试的第一步就是先确定一个效率最高的重载版本,之后再去检查它们各自引起的堆内存分配。&/p&&h4&“效率之王”&/h4&&p&为此,我们在&strong&5.X版本的Unity&/strong&中准备一个空白的场景并实现一个简单的计时器,之后就可以开始测试了。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&using S
using System.D
/// &summary&
/// 简易的计时类
/// &/summary&
public class YiWatch : IDisposable
#region 字段
private string testN
private int testC
#endregion
#region 构造函数
public YiWatch(string name, int count)
this.testName =
this.testCount = count & 0 ? count : 1;
this.watch = Stopwatch.StartNew();
#endregion
#region 方法
public void Dispose()
this.watch.Stop();
float totalTime = this.watch.ElapsedM
UnityEngine.Debug.Log(string.Format(&测试名称:{0}
总耗时:{1}
单次耗时:{2}
测试数量:{3}&,
this.testName, totalTime, totalTime / this.testCount, this.testCount));
#endregion
&/code&&/pre&&/div&&p&自定义的组件TestComp,以及我们的测试代码,每一个方法会被调用1000000次以便于观察测试结果:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&
int testCount = 1000000;//定义测试的次数
using (new YiWatch(&GetComponent&&&, testCount))
for(int i = 0; i & testC i++)
GetComponent&TestComp&();
using (new YiWatch(&GetComponent(typeof(T))&, testCount))
for(int i = 0; i & testC i++)
GetComponent(typeof(TestComp));
using (new YiWatch(&GetComponent(string)&, testCount))
for(int i = 0; i & testC i++)
GetComponent(&TestComp&);
&/code&&/pre&&/div&&p&运行的结果如图(单位ms):&img src=&/v2-f52a9bed8debc3598cc4_b.png& data-rawheight=&253& data-rawwidth=&1232& class=&origin_image zh-lightbox-thumb& width=&1232& data-original=&/v2-f52a9bed8debc3598cc4_r.png&&&br&我们可以发现在Unity 5.x版本中,泛型版本的GetComponent&&的性能最好,而GetComponent(string)的性能最差。&/p&&p&做成柱状图可能更加直观:&/p&&img src=&/v2-58a69a15cebcaf66c8abb_b.png& data-rawheight=&1107& data-rawwidth=&1141& class=&origin_image zh-lightbox-thumb& width=&1141& data-original=&/v2-58a69a15cebcaf66c8abb_r.png&&&p&接下来,我们来测试一下我们感兴趣的堆内存分配吧。为了更好的观察,我们把测试代码放在Update中执行。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&void Update()
for(int i = 0; i & testC i++)
GetComponent&TestComp&();
&/code&&/pre&&/div&&p&同样每帧执行1000000次的GetComponent方法。打开profiler来观察一下堆内存分配吧:&/p&&p&&img src=&/v2-44a9c9a5f37a2cd3f02eb_b.png& data-rawheight=&1092& data-rawwidth=&1987& class=&origin_image zh-lightbox-thumb& width=&1987& data-original=&/v2-44a9c9a5f37a2cd3f02eb_r.png&&&br&我们可以发现,虽然&strong&频繁调用GetComponent时会造成CPU的开销很大,但是堆内存分配却是0B&/strong&。&/p&&p&但是,我和朋友聊天偶尔聊到这个话题时,朋友说有时候会发现每次调用GetComponent时,在profiler中都会增加0.5kb的堆内存分配。不知道各位读者是否有遇到过这个问题,那么是不是说GetComponent方法有时的确会造成GC呢?&/p&&p&答案是否定的。&/p&&p&这是因为朋友是在&strong&Editor中运行&/strong&,并且&strong&GetComponent返回Null&/strong&的情况下,才会出现堆内存分配的问题。&br& 我们还可以继续我们的测试,这次把TestComp组件从场景中去除,同时把测试次数改为100000。我们在Editor运行测试,可以看到结果如下:&br&&img src=&/v2-0a9c5451dfb0de2aaae0bd49428caea3_b.png& data-rawheight=&684& data-rawwidth=&1341& class=&origin_image zh-lightbox-thumb& width=&1341& data-original=&/v2-0a9c5451dfb0de2aaae0bd49428caea3_r.png&&&br&10000次调用GetComponent方法,并且返回为Null时,观察Editor的Profiler,可以发现每一帧都分配了5.6MB的堆内存。&/p&&p&那么如果在移动平台上调用GetComponent方法,并且返回为Null时,是否会造成堆内存分配呢?&/p&&p&这次我们让这个测试跑在一个小米4的手机上,连接profiler观察堆内存分配,结果如图:&/p&&img src=&/v2-e55e9fbddd11ac86a86ea803e038be4a_b.png& data-rawheight=&703& data-rawwidth=&1363& class=&origin_image zh-lightbox-thumb& width=&1363& data-original=&/v2-e55e9fbddd11ac86a86ea803e038be4a_r.png&&&p&可以发现,在手机上并不会产生堆内存的分配。&/p&&h4&Null Check造成的困惑&/h4&&p&那么这是为什么呢?其实这种情况只会发生在运行在Editor的情况下,因为Editor会做更多的检测来保证正常运行。而这些堆内存的分配也是这种检测的结果,它会在找不到对应组件时在内部生成警告的字符串,从而造成了堆内存的分配。&/p&&blockquote&&p&We do this in the editor only. This is why when you call GetComponent() to query for a component that doesn’t exist, that you see a C# memory allocation happening, because we are generating this custom warning string inside the newly allocated fake null object.&/p&&/blockquote&&p&所以各位不必担心使用GetComponent会造成额外的堆内存分配了。同时也可以发现只要不频繁的调用GetComponent方法,CPU的开销还是可以接受的。但是频繁的调用GetComponent会造成显著的CPU的开销的情况下,各位还是对组件进行缓存的好。&/p&&h4&属性访问器的性能&/h4&&p&既然聊了GetComponent方法的性能,接下来我们可以继续来聊聊和GetComponent功能有些类似的,Unity脚本系统中的一些属性访问器的性能。&br& 我们最常见的属性访问器大概算是transform和gameObject了吧,当然,如果使用过4.x版本的朋友应该还会知道rigidbody、camera、renderer等等。但是到了5.x时代,除了gameObject和transform之外的属性访问器都已经被弃用了,相反,5.x中会使用 GetComponent&&来获取它们:&/p&&img src=&/v2-6fab960a524b7_b.png& data-rawheight=&721& data-rawwidth=&1642& class=&origin_image zh-lightbox-thumb& width=&1642& data-original=&/v2-6fab960a524b7_r.png&&&p&所以从4.x升级到5.x之后,这些访问器就无法使用了,所以升级引擎时各位可以关注一下自己的代码中是否有类似的问题。&/p&&p&好了,我们接着在测试中加入使用访问器获取Transform组件的效率:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&
using (new YiWatch(&transform&, testCount))
for(int i = 0; i & testC i++)
transformTest = this.
&/code&&/pre&&/div&&p&运行1000000次,结果如下(单位ms)&/p&&img src=&/v2-a47eeea900cb1a2d757273_b.png& data-rawheight=&144& data-rawwidth=&944& class=&origin_image zh-lightbox-thumb& width=&944& data-original=&/v2-a47eeea900cb1a2d757273_r.png&&&p&单次的耗时是0.000026ms,性能要远好于调用GetComponent&&方法,所以是否缓存类似gameObject或者transform这样的属性访问器似乎对性能的优化帮助不大。当然写代码和个人的习惯关系很大,如果各位早已习惯缓存这些属性访问器自然也是不错的选择。&/p&&br&&br&&h2&0x03 总结&/h2&&p&通过以上测试,我们可以发现:&/p&&ul&&li&频繁的调用GetComponent方法会造成CPU的开销,但是对GC几乎没有影响。&/li&&li&Profiler不要用来分析Editor中运行的项目,由于一些引擎内部的检查会导致结果出现较大偏差。&/li&&li&5.X版本中GetComponent&&的性能最好。&/li&&li&使用属性访问器来访问一些内建的属性例如transform的性能已经可以让人接受了,并不一定非要缓存这些属性。&/li&&li&5.X版本删掉了很多属性访问器,基本上只保留了gameObject和transform。&/li&&/ul&&p&最后需要说明的是,上述的测试发生在5.X版本的Unity中。如果使用4.x版本可能会有些许不同,例如在4.X版本中,GetComponent(typeof)的性能可能要好于GetComponent&&,而且能够直接使用的属性访问器也更多,各位可以自己进行测试。&/p&&br&&br&&p&-华丽的分割线-&/p&&br&&p&欢迎大家关注我的公众号慕容的游戏编程:chenjd01&/p&&img src=&/v2-ce71b8c86ed04d665d784dcb98094d43_b.png& data-rawheight=&400& data-rawwidth=&400& class=&content_image& width=&400&&&br&&p&最后打个广告,欢迎支持我的书&a href=&/?target=https%3A///.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《Unity 3D脚本编程》&i class=&icon-external&&&/i&&/a&~&/p&&img src=&/v2-5dd4b158fa2e980fcc840ba859d10e10_b.jpg& data-rawheight=&398& data-rawwidth=&296& class=&content_image& width=&296&&
0x00 前言在很长一段时间里,Unity项目的开发者的优化指南上基本都会有一条关于使用GetComponent方法获取组件的条目(例如14年我的这篇博客)。有时候还会发展为连一些Unity内部对象的属性访问器都要小心使…
4月26日收到了腾讯的offer,终于安心了,很多小伙伴们要我写面经介绍下,其实自己能拿到腾讯的offer 99%是运气~, &br&&br&
这里就介绍下自己的面经跟总结自己的看的书跟学习方法, &br&&br&
自己来自一所非985垫底的211大学)~大三本科,主要学习的是Linux内核/C++,投的岗位都是后台开发,&br&&br&
自己的项目也就2个demo,一个简易kernel,一个很简单的网络库. &br&&br&
因为学校位置不方便,只投了腾讯跟美团.不可以投那么多互联网公司(路费.一出疆就上千),美团各种原因放弃了, &br&&br&
然后就这次到西安参加腾讯面试花了1800左右,拿到了腾讯的offer就不打算再找了,结束自己的春招求职. &br&&br&
以下是自己面腾讯的坎坷经历,只记得部分问题,很多都忘了,见谅 &br&&br&&br&&br&
-----------------腾讯电面----------------- &br&&br&
4月10日,是日也,天朗气清、惠风和畅,手机突然显示来自深圳腾讯的电话,惊慌失措中…… &br&&br&
(因为内推失败,然后笔试时间因为个人原因错过了,怎么腾讯面试官还给我电话) &br&&br&
然后就在路边进行了电话面试…… &br&&br&
面试内容如下: &br&&br&
1.c++的static关键字的作用(我从elf结构,链接过程来回答) &br&&br&
2.内联函数跟普通函数区别(从反汇编角度来回答) &br&&br&
3.select跟epoll的区别(epoll内核源码看过,从内核实现角度回答,所以回答的不错), &br&&br&
small插曲:对于很多博客说epoll使用了共享内存,我说完全错误的,然后就扯到共享内存的内核实现(基于tmpfs,为何2个进程映射同一个文件会映射到同一片物理内存,根本机制是page
cache) &br&&br&
4.STL中的迭代器失效问题 &br&&br&
5.指针,引用区别(反汇编分析,其实汇编指令实现都一样,可以把引用看做编译器管理的指针,语法糖) &br&&br&
6.Linux相关cpu内存网络相关指令 &br&&br&
7.父子进程fork时,打开的文件的偏移量是否是相同的(从内核角度看,父子进程fork会将file文件复制一份,所以肯定会的) &br&&br&
8.Linux虚拟地址空间(3G以上内核,因为进程创建时,内核的页表全部拷贝到进程第768页目录项以上的,3G以下则是代码段(.init节,.text节,.rodata节),数据段(.data节,.bss节),堆(brk指针),栈从3G往下) &br&&br&
9.【计算机网络】只问了time_wait的危害,三次握手,四次断开 &br&&br&
10.c++多态的机制实现(虚函数表,看过深度探索c++对象模型的都会的) &br&&br&
11.vector跟list区别,还有map的底层实现(红黑树) &br&&br&
12.extern关键字 &br&&br&&br&&br&
50分钟电话面试~then接到去西安面试的通知 &br&&br&&br&&br&&br&&br&&br&&br&
讲一波心路历程: &br&&br&
其实去西安面试心里很忐忑的,毕竟腾讯的面试都比较难,而感觉自己非常渣,然后路费都要1k5+,本来都放弃了…… &br&&br&不过,4月15号灰机来到西安,整夜辗转难眠…… &br&&br&&br&&br&
【安利一波~】 &br&&br&
腾讯面试点,五星级酒店,可谓是辉煌而精致,土豪中带着典雅,优雅中充满了艺术气息,奢华而不失内涵~腾讯土大哥 &br&&br&
一面10:30,签到..等待面试地点通知... &br&&br&
-----------------一面--------------------- &br&&br&
别说我low(好吧,我可能就是比较low)来到一个非常豪华的房间面试,面试官让我做自我介绍... &br&&br&
程序化中:我来自xxx大学,对xx很感兴趣,....(此处省略) &br&&br&
then面试官把代码题给我看 &br&&br&
1.一个数组传递到函数,蜕变成指针,求字节数 &br&&br&
2.定义在全局的对象,定义在堆中对象,定义在静态局部变量对象,定义在栈中的对象,析构函数的析构顺序(从函数汇编角度看待,非常容易这道题) &br&&br&
3.new int[10]跟new int[10]()区别 &br&&br&
4.epoll的多选题.....正确答案只有一个... &br&&br&
5.让手写代码,求二叉树的翻转(镜像问题),刚好我在刷题的时候,刷过,还给女朋友讲过这道题,自己用了非递归队列实现,也用了递归实现,面试官觉得还行,就看了看我简历. &br&&br&
6.问到epoll跟select实现区别, &br&&br&
#好了~终于轮到我装逼了!# &br&&br&
从linux内核源码分析epoll的实现..把面试官忽悠住了.夸我很不错,有深度。 &br&&br&
#果然装逼有时效,猝不及防面试哥哥一个问题抛来# &br&&br&
epoll的ET模式时,如果数据只读了一半,也就是缓冲区的数据只读了一点,然后又来新事件了..怎么办. &br&&br&
我当时听错了,一脸懵逼,结果乱猜了..面试官也猜到了..就没问了 &br&&br&
(实际,fd都要支持内核的poll机制,新事件对应的fd.会把当前进程注册到等待队列,同时设置回调函数.,等fd对应的设备就绪时会唤醒等待队列中的进程,然后放入就绪链表..等等.肯定会继续啊) &br&&br&
然后又扯到网上那些破博客说什么epoll用了共享内存,一派胡言,把共享内存的实现说了一遍,基于tmpfs,然后tmpfs有什么不同,就扯到文件系统了... &br&&br&
7.红黑树,普通二叉树,AVL树,完全二叉树的区别(很简单,数据结构书都有) &br&&br&
8.编写c语言程序判断该大小端 &br&&br&
9: linux内核解决惊群问题 &br&&br&
10.hash碰撞,Trie树 &br&&br&
11.map /set容器的实现原理(红黑树知识+STL容器内部原理) &br&&br&
Q:熟悉shell么.. &br&&br&
A:不怎么熟悉 &br&&br&
Q:说说tcp/udp区别, &br&&br&
(OK,轮到我装逼了~) &br&&br&
A:我把如果基于udp如何实现可靠传输说了一遍(网上有教程),然后udp啥一般用于视频传输,丢包几乎不影响,tcp有拥塞避免,流量控制,慢启动,快速回复算法,什么的都说了一通 &br&&br&&br&&br&
切换至聊天模式~(面试官S. 我B) &br&&br&
S:你有什么想问的呢 &br&&br&
B:我技术有什么缺陷, &br&&br&
S:在同级的人中算非常深入的研究这些技术的本质,基础非常不错,对内核也有不错的了解(看来我忽悠住了~),但感觉你缺少实践,书看的非常多,知识掌握也不错,就是实践差了点,不过你可以来腾讯实习,对你会很有帮助的.我会尽快安排你二面的.. &br&&br&
S:因为你是从外地过来,让你高兴高兴,直接过了一面,等待晚上短信通知复试吧 &br&&br&&br&&br&
...哈哈哈哈好高兴呀~~~啦啦啦啦啦 &br&&br&&br&&br&&br&&br&
只能说又tmd一夜没睡好,持续性辗转难眠,间接性紧张失眠……尼玛其他人一面过后都要很久才收到二面,我tmd第二天9:30就二面...好坑啊啊啊.. &br&&br&
一夜醒来三次,紧张到不行,8:40就到了酒店签到,9:23收到面试房间号.. &br&&br&&br&&br&
-----------------二面--------------------- &br&&br&
一进门,面试官又tmd让我自我介绍,程序化中xxxxxxxxx....省略.. &br&&br&
他只提了一个问题,让我说说自己最熟悉的一部分。What?!我擦....我想想.. &br&&br&
灵光一闪~想到Linux内核的内存管理机制, &br&&br&
就把Linux内核的物理内存管理(numa,uma架构,ZONE,PAGE,伙伴算法,SLAB机制, &br&&br&
冷热页缓冲机制基于LRU,OOM内存溢出机制,struct page跟物理内存的映射,page
cache,还有swap分区等等), &br&&br&
虚拟内存管理,高端映射,(进程pcb中的mm_struct结构指向整个进程的虚拟内存空间,vm_area_struct结构.堆栈,数据段,代码段什么的,malloc实现机制,mmap映射) &br&&br&&br&&br&
(说了非常久,希望唬住面试官..结果悲剧惹……面试官懂Linux内核.你不废话嘛~二面面试官可是部门总监) &br&&br&
指出了几个错误(自己挖的坑(具体的就不说了..对看面经的同学没啥用)) &br&&br&&br&&br&
不想说面试官全程对我微笑,莫名心虚…… &br&&br&
然后聊到如何防止内存泄漏,把c++11的智能指针还有auto_ptr的实现说了一遍), &br&&br&&br&&br&
然后面试官又微笑~(面试官:S.我:B) &br&&br&
S:技术说了这么多很累了吧,你觉得自己最大的缺点是什么. &br&&br&
B:现实不会主动问人或者与人交朋友,不过在网上很活跃 &br&&br&
S:你是键盘侠吧(开玩笑中……) &br&&br&
B:当然不是 &br&&br&
S:你的表达能力还是要改善改善. &br&&br&
B:我意识到这方面了,所以经常给我同学讲解c/c++知识还有算法题,希望提高自己的语音表达能力, &br&&br&
S:那就很好.你今后的职业规划是怎样的 &br&&br&
B:我会继续读Linux内核,因为我对内核的实现机制非常感兴趣还有底层的实现机制,还有会往分布式存储(乱说的)发展,希望自己技术得到非常大的提升. &br&&br&
S:你书读了很多,基础非常不错,对技术也有很深的探索,就是缺少实践,做的都是demo,需要来公司实践, &br&&br&&br&&br&
【接下来就是面试官装逼time.默默聆听中……】 &br&&br&
把他那部门给夸的天花乱坠,什么负责整个腾讯虚拟币支付啥的,说我在他那部门实习技术会得到很大提升, &br&&br&
他有个带了10年的徒弟也一直在研究内核什么的,现在非常强,让我不要放弃继续研究内核实现. &br&&br&&br&&br&
然后问我还有什么问题,我说我从外地过来的,能否直接告知我结果 &br&&br&
面试官直接说:你过了二面,等待hr面试吧,我会尽快把你简历给hr,让你早点回学校QAQ. &br&&br&&br&&br&
-----------------HR面--------------------- &br&&br&&br&&br&
下午hr面试,躺在床上睡觉,被hr的电话吵醒来,问我方便么 &br&&br&
(腾讯非常人性化,很多人hr面都是现场面试,而西安的hr要明天才到西安,然后我在外地,所以直接给我电话面试) &br&&br&
问哪里人什么的..有木有女朋友,什么是否是独生子.其实就是闲聊........ &br&&br&
hr问了10多分钟就挂了电话~ &br&&br&&br&&br&&br&&br&
有些小伙伴们问我看了哪些书,其实c/c++后台开发就那些经典书 &br&&br&
另外介绍一点人生的经验:选购书籍.尽量选择国外的书...原因不多说,另外从豆瓣里选择书籍,看评论,评分 &br&&br&
以下是自己看的书籍介绍 &br&&br&&br&&br&
汇编部分: &br&&br&
汇编语言(masm汇编,王爽写的非常不错) &br&&br&
x86从实模式到保护模式(学习kernel必备,保护模式是一大坑) &br&&br&&br&&br&
c/c++部分: &br&&br&
C++ Primer(入门必备(但并不是0基础可以看,0基础看C++ Primer Plus) &br&&br&
Effective C++,More Effective C++(提升c++的编程技巧,面试官很多都从这书里问) &br&&br&
深度探索c++对象模型(了解c++的底层实现机制,不然面试官问了多态的实现,你不会就挂了) &br&&br&&br&&br&
STL部门:C++标准库(侯捷)(介绍STL六大组件的应用) &br&&br&
STL源码剖析(STL的源码,不过自己只看了一半而已) &br&&br&
范型编程与STL(绝版书,不过讲解traits时非常的nice) &br&&br&&br&&br&
操作系统概念部分 Linux鸟哥私房菜(linux相关命令操作,不过自己推荐the linux command
line这电子书更棒) &br&&br&
《轻松学用linux shell编程》(shell学习相关的) &br&&br&
现代操作系统(非常经典的操作系统书,不要看国内的操作系统书) &br&&br&
深入理解计算机系统(CSAPP)(豆瓣高达9.0以上的书,含金量就不多说了,其中的第7章有关elf看懂了,那就不必看那本程序员的自我修养了) &br&&br&&br&&br&
操作系统内核部分: &br&&br&
操作系统真象还原(教你怎么从0实现一个kernel,看完对操作系统绝对有一个飞一般的认识,另外作者钢哥非常棒 &br&&br&
,我经常骚扰他问内核问题,都会耐心回答) &br&&br&
Linux内核源代码情景分析(毛德操所写的2.4内核源码,感觉非常有深度,自己囫囵吞枣的看完,细节部门略过了) &br&&br&
Linux内核设计与实现(一本比较薄的2.6内核剖析书,很容易看懂其内幕) &br&&br&
深入分析Linux内核源代码(一本绝版书,陈莉君教授所写的2.4内核源代码,配合Linux内核源代码情景分析使用,效果更佳) &br&&br&
深入理解Linux虚拟内存管理(这本才刚开始看,没看多久) &br&&br&
Linux环境编程:从应用到内核(一本非常棒的新书,讲解apue的api背后的内核实现,作者我也加了,内核功底非常深厚) &br&&br&&br&&br&
计算机网络: &br&&br&
(计算机网络:自顶向下,不过学院那本谢仁希的还凑合吧) &br&&br&
tcp/ip详解卷1(腾讯课堂有明教教主讲解这本书) &br&&br&
网络编程: &br&&br&
Unix环境高级编程,Unix网络编程(这两本就不多说了,unix的圣经), &br&&br&
linux 高性能服务器编程(国内写的一本不错的书) &br&&br&&br&&br&
数据库那块自己很弱只看了mysql必知必会,redis入门实战 ~面试时也没问到数据库相关的,运气爆棚~ &br&&br&&br&&br&
算法与数据结构: &br&&br&
自己的算法能力都很弱,这里只推荐那些算法比较弱的同学: &br&&br&
数据结构与算法分析(维斯),还有剑指offer题必须刷完,leetcode,编程之美也最好刷一刷, &br&&br&
,那算法那块就没问题了,当然这里指的是普通的开发岗位,而非算法岗 &br&&br&&br&&br&&br&&br&
设计模式: &br&&br&
《设计模式:可复用面向对象软件的基础》,还有博览网上面的c++设计模式视频 &br&&br&&br&&br&
辅助类的网址 &br&&br&
牛客网(&a href=&/?target=http%3A//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&牛客网-专业IT笔试面试备考平台,最全C++JAVA前端求职题库,全面提升IT编程能力&i class=&icon-external&&&/i&&/a&),牛客网上瘾有剑指offer,leetcode等各大互联网公司的涉及操作系统,数据结构什么的选择题,填空题,编程题,非常不错 &br&&br&
还有各路大牛的面经,各种公司的内推什么的,感觉是校招必备的网址 &br&&br&&br&&br&
当然最重要的一点,光看书远远不够,需要不断的写代码,才能提高编程能力,现在很多公司都要手写代码,所以这方面也要练练 &br&&br&
以上是小弟的面试经历~End &br&&br&作者:赛罗·奥特曼(自己啦)&br&链接:&a href=&/?target=https%3A///discuss/26045%3Ftype%3D0%26order%3D4%26pos%3D8%26page%3D1& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&新疆学子的腾讯后台开发的面经_笔经面经_牛客网&i class=&icon-external&&&/i&&/a&&br&来源:牛客网
4月26日收到了腾讯的offer,终于安心了,很多小伙伴们要我写面经介绍下,其实自己能拿到腾讯的offer 99%是运气~, 这里就介绍下自己的面经跟总结自己的看的书跟学习方法, 自己来自一所非985垫底的211大学)~大三本科,主要学习的是Linux内核/C++,投的岗位都是后台…
&p&&b&先来说一说debug的基本步骤,当程序中出现bug的时候,可以按照以下步骤进行排查:&/b&&/p&&p&1. 重新读一遍程序。按照自己当初想的思路,走一遍程序,看看程序是不是按照自己的思路在走。(因为很多时候,你写着写着就忘了很多事儿)这种方式是最有效最快速的 Debug 方式。&/p&&p&2. 找到一个非常小非常小的可以让你的程序出错的数据。比如空数组,空串,1-5个数的数组,一个字符的字符串。&br&&/p&&p&3. 在程序的若干位置输出一些中间结果。比如排序之后输出一下,看看是不是真的按照你所想的顺序排序的。这样可以定位到程序出错的部分&/p&&p&4. 定位了出错的部分之后,查看自己的程序该部分的逻辑是否有错。&/p&&p&在第4步中,如果无法通过肉眼看出错误的部分,就一步步“模拟执行”程序,找出错误。&/p&&br&&p&&b&另外,这里有四种debug的技巧,可以参考一下,希望可以帮助你更高效地检查bug。&/b&&/p&&h2&&b&技巧1: 打印中间结果&/b&&/h2&&p&依赖于IDE的断点调试,是十分浪费时间的一种调试方法。而且在面试中,你是基本没有断点调试的机会的(因为很多公司是白板写题,不会提供给你IDE)。事实上在实际的工作中,你也很少能够有机会去进行断点调试,比如你进行的是 Web 开发,你只能想方设法的在代码中打印一些 Log,然后根据 Log 去分析出错的原因。你平时用 IDE 写代码,就十分容易养成这种断点调试的“坏习惯”。一个更好的方式,是使用打印中间结果的方式。以 LintCode 上的 Clone Graph 为例子:&/p&&img src=&/v2-571cdc459ea7dac6833d_b.jpg& data-rawwidth=&2270& data-rawheight=&528& class=&origin_image zh-lightbox-thumb& width=&2270& data-original=&/v2-571cdc459ea7dac6833d_r.jpg&&&p&LintCode 支持自己出测试数据进行测试的模式,点到“Testcase” 这个 tab之后,输入测试数据,点 Run Code。你的程序中的输出也会被显示在 Output 中。我们看到 代码中 第22行到27行,是在打印一个中间结果,这个中间结果就是在使用了 bfs 算法之后,从一个点出发,找到的所有的图中其他节点。这样我们就可以迅速验证,代码出错到底是因为 BFS 写错了,还是因为其他的部分写错了。&br&&/p&&p&使用这种调试方法的另外一个好处是,你很自然的希望你的程序可以“分阶段”输出一些中间结果,这种分阶段处理的方式,也是我们在课上经常强调的,把大问题变成小问题,然后逐个击破的编程思想。养成这种编程习惯之后,可以非常有效的帮助你在写程序的时候,就避免掉错误。&br&&/p&&h2&&b&技巧2: 一行一行改成参考程序 &/b&&br&&/h2&&p&在九章的官网 &a href=&///?target=http%3A///solutions/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&/solutions/&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a& 中有 LC 完整的参考程序库,其中 Java 程序的一部分代码是我自己亲自编写的,具备较高的质量和参考价值。很多题目也给了多种不同的解法。比如 Binary Tree Level Order Traversal 这一题,给出了三种 BFS 的参考程序和 1个 DFS的参考程序:&a href=&///?target=http%3A///solutions/binary-tree-level-order-traversal/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&/solutions/&/span&&span class=&invisible&&binary-tree-level-order-traversal/&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a& 。通常来说很多题目,你不仅仅需要掌握其中一种方法,而是需要掌握这个题所有的解决办法。&br&&/p&&p&有不少同学经常会来问我:“老师,我的代码和参考程序一样啊,为什么还是不对。” 这种时候,我通常建议他们,将自己的代码,一行一行的改成参考程序。这样,当他们发现哪一行代码不一样的时候,就自然定位到了错误。&br&&/p&&p&举一个例子,就以 Binary Tree Level Order Traversal 为例,宽度优先搜索算法(BFS)是面试必须掌握的一种算法。来看看下面这个有错误的代码(请花3分钟阅读一下,并找出错误所在):&/p&&img src=&/v2-dff7b0874cade98c627ba1_b.jpg& data-rawwidth=&1308& data-rawheight=&988& class=&origin_image zh-lightbox-thumb& width=&1308& data-original=&/v2-dff7b0874cade98c627ba1_r.jpg&&&p&&br&从程序思想上来看,好像并没有什么错。很难直接发现有什么问题。与参考程序逐行对比之后会发现,错误发生在第14行。&/p&&p&参考程序中,写法是:&/p&&img src=&/v2-94f70ff158_b.png& data-rawwidth=&1200& data-rawheight=&88& class=&origin_image zh-lightbox-thumb& width=&1200& data-original=&/v2-94f70ff158_r.png&&&p&&br&和上面的程序写法是:&/p&&img src=&/v2-e21c5e876d17d662a4c9fe115df640ec_b.png& data-rawwidth=&1016& data-rawheight=&54& class=&origin_image zh-lightbox-thumb& width=&1016& data-original=&/v2-e21c5e876d17d662a4c9fe115df640ec_r.png&&&p&&br&这两种写法存在巨大区别,原因是在循环体内部,我们会不断往 queue 中放东西,这导致了queue.size() 的值是不断变化的。而没有起到我们只想循环当前这一层所有点的功能。&/p&&p&通过对这个程序逐行对比,我们能够马上学会如下的知识点:&br&&/p&&ol&&li&for循环中间的判断语句,在循环体的每一次循环中都会被重复执行,而不是在一开始就确定好执行多少次。&/li&&li&为了做到BFS的分层遍历,需要先把 size 取出来,再 for循环这个size,这是BFS分层遍历中最关键的一句话。&/li&&/ol&&h2&&b&技巧3: 给小熊讲程序 &/b&&br&&/h2&&p&这个技巧,是我曾经参加高中生算法竞赛的时候,一位算法竞赛国家队的前辈教我的。当时我的算法水平可能已经还不错了,但是代码质量很差,很容易写出有bug的代码。这位前辈告诉我,可以放一只 “小熊” 在你的电脑旁边,一旦程序出错了。就对着这只小熊讲你的整个代码是怎么解决问题的。因为是给小熊讲,所以你可以把它当作什么都不懂,于是需要更加仔细的去讲述你代码中每个细节,所以你需要一行一行的讲,甚至连为什么你要用 ArrayList 而不用 int[] 都要讲得清清楚楚。讲着讲着,你就有可能突然发现你的错误所在了。&/p&&p&这个技巧的意义在于,你在写代码的时候,脑子里可能想着一个事情,但是打出来的代码,可能是另外一回事儿。或者你脑子里想着有3个条件需要判断,但是打的时候,漏掉了一个。当你把代码重新讲一遍的时候,事实上是在重新整理你的逻辑,查漏补缺。这样很容易就能够发现你的错误。&br&&/p&&h2&&b&技巧4: 必杀,重写一遍 &/b&&br&&/h2&&p&大部分的bug,其实都是 typo。比如:&br&&/p&&ul&&li&大于符号和小于符号打反了&/li&&li&&= 写成了 &&/li&&li&本来要写一句话干什么来着但是后来写着写着忘记了&/li&&li&if 后面忘了加 else&/li&&li&for 循环后面忘了加括号,导致代码跑到了循环体之外&/li&&li&变量名打错:for(int j=0;i&n;j++)&/li&&/ul&&p&诸如此类,不胜繁举。重新写一遍代码, 往往都能 fix 这些问题。&br&&/p&&p&&b&推荐两篇debug方面的经典文章:&/b&&br&&a href=&///?target=https%3A//mp./s%3F__biz%3DMzA5MzE4MjgyMw%3D%3D%26mid%3Didx%3D1%26sn%3De2b24baa39fcbcb60bfe3fe%26mpshare%3D1%26scene%3D1%26srcid%3D0317VxWjGuWvI5SH38ftZCvX%26key%3Df5df4dd7bf3ad3aaa2a396aa1fedaee18e314c94eeab34bcca5a3a1f53dfb16a8ebc28038bfd%26ascene%3D0%26uin%3DMTUyMzg3NjAwMA%253D%253D%26devicetype%3DiMac%2BMacBookAir7%252C1%2BOSX%2BOSX%2B10.12.3%2Bbuild%%26version%3Dnettype%3DWIFI%26fontScale%3D100%26pass_ticket%3D0AiIToHJN8yqpuqRAsA5PaaQMJr8KtvlnZ2EqkX0zx%252BEZweRvHKyF%252ByjmycpUbVn& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&【教程】Debug 的基本步骤&i class=&icon-external&&&/i&&/a&&br&&a href=&///?target=https%3A//mp./s%3F__biz%3DMzA5MzE4MjgyMw%3D%3D%26mid%3D%26idx%3D1%26sn%3D761f8abd6ce901e4aece8d%26chksm%3D887ef509c59834daa1643ce0bfc82eddcb%26mpshare%3D1%26scene%3D1%26srcid%3D0317YrAGslunjxSVX4iFtiRI%26key%3D7e3acfcaa22ffc517c929d7c83427cdd72dbb98ce4f58d5d1eabccea0165c7fbc7db2fb18d895c26571bc6ebff3c928ef37d8cfb70d2321f90fff1a%26ascene%3D0%26uin%3DMTUyMzg3NjAwMA%253D%253D%26devicetype%3DiMac%2BMacBookAir7%252C1%2BOSX%2BOSX%2B10.12.3%2Bbuild%%26version%3Dnettype%3DWIFI%26fontScale%3D100%26pass_ticket%3D0AiIToHJN8yqpuqRAsA5PaaQMJr8KtvlnZ2EqkX0zx%252BEZweRvHKyF%252ByjmycpUbVn& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&还在断点调试?教你四种调试技巧让你快速定位错误!&i class=&icon-external&&&/i&&/a&&br&&/p&&p&&b&欢迎关注我的微信公众号:九章算法(ninechapter),精英程序员的交流社区,帮助你学习算法、找到工作、成为优秀程序员!&/b&&/p&
先来说一说debug的基本步骤,当程序中出现bug的时候,可以按照以下步骤进行排查:1. 重新读一遍程序。按照自己当初想的思路,走一遍程序,看看程序是不是按照自己的思路在走。(因为很多时候,你写着写着就忘了很多事儿)这种方式是最有效最快速的 Debug 方…
&p&先上一个index[1]: 这个index每年都有统计:&/p&&p&先看前10名:&/p&&img src=&/v2-efeb98e6ceec_b.png& data-rawwidth=&942& data-rawheight=&402& class=&origin_image zh-lightbox-thumb& width=&942& data-original=&/v2-efeb98e6ceec_r.png&&&p&前十名占据了48.831%的份额,值得注意的是,今年的前十名,大部分都是去年的前十名,被Delphi挤掉的是Ruby,今年排11名。&/p&&p&看看这十个人吧,哪个不是两鬓斑白,哪个不是业界栋梁?(要唱起来了。。)&/p&&p&Java 学java,去花儿街!&/p&&p&C/C++ 世界的基础--石器vs核动力石器哪个更好用&/p&&p&C# 我爹有钱&/p&&p&Python 让游标卡尺脱销的语言&/p&&p&PHP 世界上最好的语言&/p&&p&VB 我爹有钱&/p&&p&JavaScript 我是浏览器汇编&/p&&p&Delphi Borland:老子还活着呢!&/p&&p&Perl php,老子曾经是你爹&/p&&p&Ruby 今年也要在轨道上好好努力哟&/p&&br&&p&Reference:&/p&&p&[1]&a href=&///?target=https%3A///tiobe-index/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&TIOBE - The Software Quality Company&i class=&icon-external&&&/i&&/a&&/p&
先上一个index[1]: 这个index每年都有统计:先看前10名:前十名占据了48.831%的份额,值得注意的是,今年的前十名,大部分都是去年的前十名,被Delphi挤掉的是Ruby,今年排11名。看看这十个人吧,哪个不是两鬓斑白,哪个不是业界栋梁?(要唱起来了。。)Ja…
谢邀,手游页游和端游的服务端本质上没区别,区别的是游戏类型。&br&&br&&b&类型1:卡牌、跑酷等弱交互服务端&/b&&br&&br&卡牌跑酷类因为交互弱,玩家和玩家之间不需要实时面对面PK,打一下对方的离线数据,计算下排行榜,买卖下道具即可,所以实现往往使用简单的 HTTP服务器:&br&&img src=&/b6e288b02b8664afd843_b.jpg& data-rawwidth=&438& data-rawheight=&186& class=&origin_image zh-lightbox-thumb& width=&438& data-original=&/b6e288b02b8664afd843_r.jpg&&登录时可以使用非对称加密(RSA, DH),服务器根据客户端uid,当前时间戳还有服务端私钥,计算哈希得到的加密 key 并发送给客户端。之后双方都用 HTTP通信,并用那个key进行RC4加密。客户端收到key和时间戳后保存在内存,用于之后通信,服务端不需要保存 key,因为每次都可以根据客户端传上来的 uid 和 时间戳 以及服务端自己的私钥计算得到。用模仿 TLS的行为,来保证多次 HTTP请求间的客户端身份,并通过时间戳保证同一人两次登录密钥不同。&br&&br&每局开始时,访问一下,请求一下关卡数据,玩完了又提交一下,验算一下是否合法,获得什么奖励,数据库用单台 MySQL或者 MongoDB即可,后端的 Redis做缓存(可选)。如果要实现通知,那么让客户端定时15秒轮询一下服务器,如果有消息就取下来,如果没消息可以逐步放长轮询时间,比如30秒;如果有消息,就缩短轮询时间到10秒,5秒,即便两人聊天,延迟也能自适应。&br&&br&此类服务器用来实现一款三国类策略或者卡牌及酷跑的游戏已经绰绰有余,这类游戏因为逻辑简单,玩家之间交互不强,使用 HTTP来开发的话,开发速度快,调试只需要一个浏览器就可以把逻辑调试清楚了。&br&&br&&b&类型2:第一代游戏服务器 1978&/b&&br&&br&1978年,英国著名的财经学校University of Essex的学生 Roy Trubshaw编写了世界上第一个MUD程序《MUD1》,在University of Essex于1980年接入 ARPANET之后加入了不少外部的玩家,甚至包括国外的玩家。《MUD1》程序的源代码在 ARPANET共享之后出现了众多的改编版本,至此MUD才在全世界广泛流行起来。不断完善的 MUD1的基础上产生了开源的 MudOS(1991),成为众多网游的鼻祖:&br&&img src=&/b647b152f0c29b29e2c9_b.jpg& data-rawwidth=&368& data-rawheight=&225& class=&content_image& width=&368&&MUDOS采用 C语言开发,因为玩家和玩家之间有比较强的交互(聊天,交易,PK),MUDOS使用单线程无阻塞套接字来服务所有玩家,所有玩家的请求都发到同一个线程去处理,主线程每隔1秒钟更新一次所有对象(网络收发,更新对象状态机,处理超时,刷新地图,刷新NPC)。&br&&br&游戏世界采用房间的形式组织起来,每个房间有东南西北四个方向可以移动到下一个房间,由于欧美最早的网游都是地牢迷宫形式的,因此场景的基本单位被成为 “房间”。MUDOS使用一门称为LPC的脚本语言来描述整个世界(包括房间拓扑,配置,NPC,以及各种剧情)。游戏里面的高级玩家(巫师),可以不断的通过修改脚本来为游戏添加房间以及增加剧情。早年 MUD1上线时只有17个房间,Roy Trubshaw毕业以后交给他的师弟 Richard Battle,在 Richard Battle手上,不断的添加各种玩法到一百多个房间,终于让 MUD发扬光大。&br&&br&用户使用 Telnet之类的客户端用 Tcp协议连接到 MUDOS上,使用纯文字进行游戏,每条指令用回车进行分割。比如 1995年国内第一款 MUD游戏《侠客行》,你敲入:&go east&,游戏就会提示你:“后花园 - 这里是归云庄的后花园,种满了花草,几个庄丁正在浇花。此地乃是含羞草生长之地。这里唯一的出口是 north。这里有:花待 阿牧(A mu),还有二位庄丁(Zhuang Ding)”,然后你继续用文字操作,查看阿牧的信息:“look a mu”,系统提示:“花待 阿牧(A mu)他是陆乘风的弟子,受命在此看管含羞草。

我要回帖

更多关于 网龙的子公司有哪些 的文章

 

随机推荐