• 关于

    空搜索有什么用

    的搜索结果

回答

流读取了就没了。######回复 @打哭你 :流对应的是数据,数据放在内存中,有的是部分放在内存中。read 一次标记一次当前位置(mark position),第二次read就从标记位置继续读(从内存中copy)数据。 所以这就是为什么读了一次第二次是空了。 怎么让它不为空呢?只要inputstream 中的pos 变成0就可以重写读取当前内存中的数据,但很遗憾,没找到有修改pos 的api。######好像是这样的.....这是为什么呢?百度也搜索不到相关内容###### 把拦截器去掉能接收到吗?    为什么不用@RequestParam ? ######json请求.....没用br.read()这个操作就可以接收到...######我的用json数据作为请求数据。接收的时候用@RequestParam Map<String ,Object > map   直接接收######嗯嗯....用@RequestBody好像流读取....读一次就没有了....貌似这样...######既然你用了spring MVC要做数据处理,就利用它的 HttpMessageConverter吧,不要写那种拦截器了。######  有一种方式做验证就是通过Aop,对controller的方法做切面。 在切面里面可以拿到方法的参数, @Around(" **** ") public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable ProceedingJoinPoint pjp Object[] args = pjp.getArgs(); 通过 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getResponse(); 可以拿到当前线程使用的request和response再进行校验和处理即可
爱吃鱼的程序员 2020-05-29 17:55:32 0 浏览量 回答数 0

回答

流读取了就没了。######回复 @打哭你 :流对应的是数据,数据放在内存中,有的是部分放在内存中。read 一次标记一次当前位置(mark position),第二次read就从标记位置继续读(从内存中copy)数据。 所以这就是为什么读了一次第二次是空了。 怎么让它不为空呢?只要inputstream 中的pos 变成0就可以重写读取当前内存中的数据,但很遗憾,没找到有修改pos 的api。######好像是这样的.....这是为什么呢?百度也搜索不到相关内容###### 把拦截器去掉能接收到吗?    为什么不用@RequestParam ? ######json请求.....没用br.read()这个操作就可以接收到...######我的用json数据作为请求数据。接收的时候用@RequestParam Map<String ,Object > map   直接接收######嗯嗯....用@RequestBody好像流读取....读一次就没有了....貌似这样...######既然你用了spring MVC要做数据处理,就利用它的 HttpMessageConverter吧,不要写那种拦截器了。######  有一种方式做验证就是通过Aop,对controller的方法做切面。 在切面里面可以拿到方法的参数, @Around(" **** ") public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable ProceedingJoinPoint pjp Object[] args = pjp.getArgs(); 通过 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getResponse(); 可以拿到当前线程使用的request和response再进行校验和处理即可
爱吃鱼的程序员 2020-06-02 12:00:47 0 浏览量 回答数 0

回答

流读取了就没了。######回复 @打哭你 :流对应的是数据,数据放在内存中,有的是部分放在内存中。read 一次标记一次当前位置(mark position),第二次read就从标记位置继续读(从内存中copy)数据。 所以这就是为什么读了一次第二次是空了。 怎么让它不为空呢?只要inputstream 中的pos 变成0就可以重写读取当前内存中的数据,但很遗憾,没找到有修改pos 的api。######好像是这样的.....这是为什么呢?百度也搜索不到相关内容###### 把拦截器去掉能接收到吗?    为什么不用@RequestParam ? ######json请求.....没用br.read()这个操作就可以接收到...######我的用json数据作为请求数据。接收的时候用@RequestParam Map<String ,Object > map   直接接收######嗯嗯....用@RequestBody好像流读取....读一次就没有了....貌似这样...######既然你用了spring MVC要做数据处理,就利用它的 HttpMessageConverter吧,不要写那种拦截器了。######  有一种方式做验证就是通过Aop,对controller的方法做切面。 在切面里面可以拿到方法的参数, @Around(" **** ") public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable ProceedingJoinPoint pjp Object[] args = pjp.getArgs(); 通过 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getResponse(); 可以拿到当前线程使用的request和response再进行校验和处理即可
优选2 2020-06-05 13:11:19 0 浏览量 回答数 0

问题

如何将SQL Server数据库迁移到MySQL??mysql

我有一个包含大量数据的SQL Server数据库和一个空的MySQL数据库。现在,我想将SQL Server数据库的所有数据(包括数据库架构)复制到MySQL数据库。 我曾考虑过使用原始SQL转储...
保持可爱mmm 2020-05-17 14:23:19 1 浏览量 回答数 1

问题

OpenSearch如何查询query子句?

子句说明 query子句是搜索语句中不可缺少的一部分,它表示在哪个索引字段下查询什么内容,并且可以指定多个查询条件及其之间的关系(AND\OR\ANDNOT\RANK)。例如可以将...
轩墨 2019-12-01 20:57:10 1407 浏览量 回答数 0

问题

【今日算法】4月20日-二分查找详解

先给大家讲个笑话乐呵一下: 有一天阿东到图书馆借了 N 本书,出图书馆的时候,警报响了,于是保安把阿东拦下,要检查一下哪本书没有登记出借。阿东正准备把每一本书在报警器下...
游客ih62co2qqq5ww 2020-04-20 13:50:19 4 浏览量 回答数 1

问题

我2017年的WordPress 的 SEO 优化经验分享

前言 自己用 WordPress 作为个人博客的 Web 程序差不多也有七八年了,中间也是积攒了非常多的使用经验,不过网站在搜索引擎收录这一个问题上差不多到 2017年 才摸索明白,这里也就...
妙正灰 2019-12-01 21:41:43 1693 浏览量 回答数 3

问题

服务器运维系列教程(二):服务搭建---Windows篇

        上篇简单说了关于基础管理工具和一些杂乱的小结,这篇来一些基础实用的运维操作心得。         如果说前一篇是教你如何登录到新到手的服务器,那么这一篇就该说说简单的网站服务搭建了。你不可能到手...
千鸟 2019-12-01 21:53:28 10096 浏览量 回答数 2

问题

《阿里感悟》-如何成为一名优秀的新人

成为一名优秀的新人,我认为要做到三点:良好的心态,积极的思考和高效的学习。 良好的心态 良好的心态包括两部分学习和做事。 学习的心态。空杯子才可以装下更多的东西。所以无论多牛的新人...
小柒2012 2019-12-01 22:03:45 3803 浏览量 回答数 2

问题

各种流行的编程风格? 400 报错

各种流行的编程风格? 400 报错 在过去的N年中,我遇到了很多使用囧然不同风格的开发者,下面是我所知道的一些,你还知道其它的吗? 散弹枪编程 这种编程风格是一种开发者使用非常随...
爱吃鱼的程序员 2020-06-04 15:18:42 1 浏览量 回答数 1

问题

人工智能技术百问——机器真的能取代人类吗

随着科技的飞速发展,“人工智能”无疑成为了当下最火的词。在这一领域,我们仍处于非常初级的阶段,很多事情我们还不了解。它企图了解智能的实质,并生产出一种新的能以人类智能相似的方式做出反应的智能机器,该领域的研究包括机器人、语言识别、图像识别、...
yq传送门 2019-12-01 20:27:57 4467 浏览量 回答数 3

问题

OSS存储利用内网CDN叠加多台5MECS网宽

阿里云超过5M的带宽太贵了,大家如果是做下载站的,如采用ECS或ECS+OSS方案的,可以采用这个方式CDN。OSS经内网反代理至多台ECS来CDN,然后提供附件下载和以下教程...
betterhomechina 2019-12-01 21:04:17 14039 浏览量 回答数 5

问题

不知道这些,谈什么网站运营!

    你真的认清网站运营究竟是什么了吗?真正意义上的网站运营是指网络营销体系中一切与网站的后期运做有关的工作。就我国目前的互联网发展趋势看,网站的运营就应当融入企业的整体经营体系中,使网络和原有的...
晨大官人 2019-12-01 22:05:41 7476 浏览量 回答数 0

问题

网站营销的360度运转

      其实你真的认清网站运营究竟是什么了吗?真正意义上的网站运营是指网络营销体系中一切与网站的后期运做有关的工作。以目前我国的互联网发展趋势看,网站的运营应当融入到企业的整体经营体系中,让网络...
晨大官人 2019-12-01 22:10:18 7818 浏览量 回答数 0

问题

搞懂了这几点,你就学会了Web编程

做了那么多年Web编程,仔细想想,其实本质上就那点事儿,你抓住了几个重点问题,学起来一点都不难。 1.理解浏览器/服务器结构(B/S) B/S是从90年代的客户端/服务器端...
技术小菜鸟 2019-12-01 21:20:38 2373 浏览量 回答数 1

回答

01「思维陷阱」是一个人职场平庸的根本原因 有没有人想过:为什么有些人在职场显得能力特别差? 我们生活在一个容易让人焦虑的时代,每天都需要主动或者被动地接受大量的信息,但少有人清醒地知道,这些信息悄悄改变了我们的“思维方式”乃至“行为”,引导我们走进陷阱。 如果你不能意识到,你可能正在被“思维陷阱”拖入平庸和焦虑的痛苦中。 为了方便理解,我下面列出三种最常见的陷入“思维陷阱”的人,对照看看自己是不是: 热衷快餐知识,却不能清醒知道自己无知的人 习惯什么都“靠自己”的人 无法一眼看透事物发展背后本质的人 **1. 热衷快餐知识 ** 却不能清醒知道自己无知的人 伴随着知识付费的崛起,近几年出现了大量热衷快餐知识的人_他们是朋友圈的“概念狂人”,对权威、意见领袖的观点非常追捧,关于最新的话题他总能发表看法,他们热衷于走捷径,转发的文章总是散发着贩卖焦虑的气味。 但如果与他们深入交流,你会发现:除了这些二手的快餐知识,他们对常识和经典无知的可怕。 这些人最大的特点是不知道自己的无知——认为自己脑子中的想法是什么样,世界就是什么样。这种人在职场有一个很难缠的习惯:很喜欢先入为主一个自己坚持的观点,然后再围绕这个观点去寻找支持论据。 如果这种人有较高的执行力,那就太可怕了——因为在他们很努力地将片面的理解付诸行动时,你根本无法说服他,一切都要等他让所有人都撞得头破血流停下来才能进行调整。 **2. 习惯 ** 什么都“靠自己”的人 如果一个人看多了鸡汤文里“什么都不如自己可靠”的口号,或者片面理解了近几年常说的“为结果负责”这句话,那他就会走入“靠自己”的思维陷阱。 这些人最大的特点就是害怕麻烦别人,害怕拒绝——认为目前事物无法圆满完成的原因,主要是自身实力或资源还不够,所以会一味地增强自身资源以期望达到目标。 他们既不能看到别人那里多余的可协作资源,也不能将自己的资源为别人所用。 因为害怕暴露出错,他们也不擅长分享和求助。 他们会觉得自己深刻理解了“责任”的意义,但是却总是感到每天的工作压力山大,那些习惯在办公室里加班到凌晨但效率低下的员工往往是这种人。 **3. 无法一眼看透事物发展背后矛盾本质的人 ** 《教父》最有名的一句话是“花半秒钟就看透事物本质的人,和一生都看不清事物本质的人,注定是截然不同的命运。” 那什么是“事物的本质”呢? 其实就是位于事物发展中底层的矛盾。 如果一个人看事物或者解决工作难题的时候,没有思考背后的矛盾和规律的习惯,就容易流于表面,他们可能洞察力不错,比起一般人能关注那些细节,但是却缺乏全局观,容易纠结在自己的小世界里。 注意:没有日常观察思考“事物发展背后的矛盾”习惯的人,注定无法成长为团队的领导者! 在职场,他们是需要反复指导和争论,耗费团队沟通成本的下属,在解决问题时,他们是无法快速清晰找到问题抓手的那群人;在生活中,他们往往又会陷入“拎不清”或“选择困难”的麻烦中。 02 那些互联网大神 是如何跳出“思维陷阱”的? “思维陷阱”就藏在人性的弱点中,它是如此可怕和不易察觉,我们必须保持一些日常思考习惯来对抗它对我们的影响。 也许你能从下面三位阿里巴巴高管身上拥有的特质中找到答案,这些习惯帮助他们克服“思维陷阱”在中国最复杂的商业经济体——阿里巴巴中取得了事业上的巨大成就。 他们是那些经历过绝望后谷底反弹的人,那些长期默默坚持而又一鸣惊人的人,那些在危急关头敢于独自按下刹车键的人,他们分别是钉钉创始人无招、盒马鲜生创始人侯毅,以及现在的淘宝天猫总裁蒋凡。 **1. 钉钉创始人无招 ** 抛下已知去“观察”外界的习惯 “无招”是花名,如果结合他在阿里的经历看,会发现很有意思。 钉钉创始人无招 2014年,阿里经历了强推社交产品“来往”的巨大挫折;在智能手机全国开始普及的年代,因为社交用户基数大,而且极度高频的入口级特性,社交产品所能带来的安全感是各大互联网厂商都极度渴望的,所以你可以理解为什么马化腾会把微信横空出世称为:抢到第一张移动互联网船票。 而陈航和他所在的团队,就是试图通过挑战微信,为阿里赢得安全感的一群人。 用再造一个“微信”来挑战微信,结果就是无招需要和团队把一场惨痛的失败消化下来。 但有没有人想过:这样的严重挫败陷入的低谷,对一个产品型的团队领导者也许是一件好事——因为绝望会让一个人抛弃原有的脑子里对世界所有的理解,进入一种彻底放空和内省状态,这时候才能静下心来观察和阅读世界真正的需要。 这与悟道的逻辑不谋而合。 作为一个产品经理可能会反思:任何大而广的东西一定有弱点,如果说微信的社交面是一条横线,需要观察寻找的,是哪里可以诞生一条尚未挖掘的纵线。 那么这条纵线是什么呢? 静心向内看就会有答案,那就是阿里生态圈的万千小B企业。 如果你进入用户的心中去“观察”他们的想法,你就会用心眼看到后面的答案。 之后被外界评价“反人性”的钉钉迅速破圈微信获得了成功,而鹅厂主打“温度”的企业微信却一直不温不火,这个现象背后原因是什么? 很多人认为是因为钉钉抓住了老板的强压执行力需求,自上而下地推动市场,所以在微信办公的大环境下撕开了一个缺口。还有人同时认为无招是个冷酷的人。 但我现在却不这样认为。 在仔细阅读和研究了关于钉钉2015年来,所有无招在公开场合的发言和对钉钉产品的理解后,我认为他是国内少有的具备高度同理心的产品经理型CEO之一。 他身上有一种放下固有认知,虚心“观察”用户内心所需的能力,而且这几乎融入了他和团队的日常习惯中。 可能连使用者自己都不知道,钉钉的成功最深处,是在碎片化办公的大环境下,人性中饱含的对深度工作专注和效率的追求。而在这一点上,无论是老板还是员工,只要他还算是 “想做事的人” 那就是共通的! 人们只会说自己要一匹更快的马,但亨利福特却能观察到人心深处对速度的追求,为人们造出汽车。 “观察”的不是表面,而应该是人的内心! 在这个状态中,最重要的是要保持不带任何预设立场的“空”,不先入为主,不画地为牢,带着无知观察世界。 你不能带着“已知”去看待市场;不能孤立地,刻板地去读那些所谓的“大数据”,也不能光靠人云亦云来判断用户真正的需求,而要用“无知”的心态去接近和观察用户——那些一个个自然人的情绪和需要,以人为本。 不然,就会像百度沉迷于搜索引擎的修补,放出了头条;腾讯放弃了对用户工作外时间使用的的观察,做大了抖音。 如果他们的产品经理愿意走出北上广高大上的写字楼,走到他们真正需要服务的“群众”中去,结合数据和实践,也许就会“观察”到——哦~原来世界不是自己坐在角落里想象的那样。 钉钉所有的员工,入职后第一课就是被要求放下已知,带着空杯进入那些小B企业中,同工同吃,“观察”和阅读用户内心真正的需要。 “无”招胜有招——《笑傲江湖》里风清扬传给令狐冲的第一句话。 **2. 盒马鲜生创始人侯毅 ** 保持“关联性”思考的习惯 说完钉钉的无招,我们再看看盒马的侯毅。 盒马鲜生创始人侯毅 侯毅这个人很有意思,因为他最早是刘强东的“兄弟”,在京东长期希望推动一个类似盒马的前瞻O2O项目,无奈一直没有人关注;最后被逍遥子识才,多次劝说后,决定加入阿里,盒马鲜生是这么来的(这里不得不说:老逍简直比老萧还厉害)。 盒马鲜生是带火了“新零售”这个概念的明星企业,但很多人其实不懂“新零售”是什么。 所谓新零售的准确定义,其实就是在各种资源的关联和协同组合中,寻求一种能大大节约成本,提高价值的新组合。 为什么代表人物会是侯毅? 你可以理解成:因为长年专注在线下线上相结合的领域,侯毅的脑子有了一个叫“资源相互联系”的魔方,每天他都需要转动几次,去寻找数个变量组合资源中,无限接近“提高价值降低成本”的最优解。 所以这样看盒马和侯毅,你就可以突然看懂了:为什么可以推出“盒区房”这种以小博大的品牌亮点,通过捆绑房地产这个敏感话题,达到巨大宣传效果;以及明白为什么在今年的艰难时期,盒马能够快速反应,第一个推出了大显身手的“共享员工”模式了。 盒马的品牌是围绕着社区服务来的,线下线上配合的打法中,作为领导者的侯毅永远不能孤立地去思考,如果只想着依靠自己的力量去发展,那就坏事了。 保持日常的关联性思考,也有助于让一般人看竞争时,不陷入二元对立的表面理解。 用“关联性”的思维来理解阿里的战略,你会发现:任何与阿里展开竞争的企业,他们需要面对的是整个的阿里军团。 比如美团面对的是饿了么和口碑吗?那么盒马呢?大润发呢?银泰呢?支付宝呢?阿里云呢?天猫超市呢? 所以作为普通人,你可以学到的是永远不要只想着只用自己的资源和能力去做事。 一定要懂得资源之间的“关联性”,不要怕麻烦别人,也许你也能给别人创造价值呢?所以,你也可以在大脑中培养一个“关联性”思考事物的魔方。 **3. 淘宝天猫总裁蒋凡 ** 思索事物发展背后矛盾的习惯 当宣布蒋凡挑大梁的时候,很多人会问:为什么张勇和马云会选择一个少壮派? 淘宝天猫总裁蒋凡 也许张勇最能理解蒋凡:因为他们都是那种“在关键时刻孤独地扮演过‘扳道工’角色的人”——无论当时对他们来说,自己在不在最重要的位置上。 在蒋凡身上,有着外界所说的“一眼看穿底层逻辑”的能力;也是当下信息爆炸的时代,一种透过乱七八糟的消息迷雾,看到复杂事物中最简单的常识的能力。 这种能力,就是要看透推动事物发展背后的矛盾。 一个外表复杂的事物,它的本质其实是常识,就像新闻联播里每天在说的“当下主要矛盾已经转化为人民日益增长的美好生活需要和不平衡不充分的发展之间的矛盾”。 到底什么是“消费升级”? 必须要用矛盾的观点看: 我们这些五环内白领在双11抢不到戴森吸尘器的不是真正的主要矛盾,你看不到的地方,“国内的大多数”的小镇青年想买一件耐克配国潮,而自己所处的城镇既没有CBD和没有大商场,下班时间甚至都不知道怎么打发——这才是主要矛盾。 去拼多多拼个9块9的手纸,被五环内用户嘲讽为“消费降级”,可你要知道拼多多的手纸不是为你准备的,是为广大“中国的大多数”准备的——这,才是真正的消费升级! 但在那个年代,并不是所有人都能认清主要矛盾。 当时即使在阿里内部,长年的竞争也让一部分人陷入了思维陷阱,认为京东是天猫最大的追赶者。 那时候也有人知道小镇青年的重要性,可是当时大家的理解还停留在跑到农村去刷墙。 拼多多为什么能够在阿里眼皮下迅速崛起呢!? 如果说是把握了下沉市场还是流于表面,你用矛盾的观点看本质: 第一点,2015~2017年间,大量阿里生态内的小小B端的角色,如底层商家、淘客、羊毛党因为阿里战略调整,对外发生了外溢,这些互联网游牧民走到哪,哪里就形成了新的细小供应链——这些人离开阿里要吃饭啊,这是最主要矛盾。 第二点,低价智能机和微信支付相结合,带来了小镇青年整体电商用户盘子扩大——这些人的日常时间要怎么打发,身边可能连个高级商场都没有,这是次主要矛盾。 这些东西,身处五环内的你在那个年代里,光看数据是不会马上发现的,只有靠细微的洞察才能感知到: 快递小哥的包裹里是不是开始有了别的平台的商品? 老家父母亲戚的朋友圈,是不是很多东西变了? 地方台的的综艺节目里面,广告赞助商是不是出现了不认识的牌子?(可惜很多北上广人不看电视) 那些像游牧民族一样的羊毛党,被你屏蔽朋友圈的微商妈妈又在忙什么? 透过现象看本质,拼多多就是抓住了这些要素悄悄长大的。 蒋凡上任后面对这个需要被再次重视的市场,是怎么抓“主要矛盾”的? 首先是重新平衡天猫、淘宝的重心,平衡“大多数用户”和B端之间的消费和供给——这不是拿捏尺度的平面问题,而是一个对顶层架构重新分析、设计的立体问题。 选用模式更适合五环外市场的聚划算做渠道下沉,向低线城市渗透、并且覆盖全年龄段,尽快封堵挤压拼多多的继续扩张 发力短视频、抖音、网红,直播这些内容场景,再通过大数据精准推送,通过占领用户时间,赢得市场,让B端人群比如主播网红下沉去填补C端的使用手机时间。 带领品牌商家下沉。之前很多品牌集中在打一二线市场,原有的渠道网络对于下沉市场是滞后的。但随着阿里的强势运营,优质的中部商家做敲门砖品牌迅速得以下沉——提前占住山头,让对手仰攻。 随着最近淘宝特价推出,结合淘宝、聚划算、天猫、淘小铺全面出击,阿里军团的刀枪剑戟朝向了同一个方向:B端搭建架构,C端占领时间,蒋凡完成了对北上广人群和下沉市场的一记全垒打! 目前我们还不知道拼多多的黄铮会如何接下蒋凡这一记硬球——因为占据了品牌优势,拼多多对阿里会长期处于一种“仰攻”状态。 这就难受了,毕竟狮子猛回头扑向一只咬自己尾巴的鬣狗很容易,但鬣狗要一口吃下一只狮子却很难。 03 你该如何训练“三种思维” 获得职场成功! 写到这里,你也许会说:似乎这些思维习惯也没有多么的深奥啊?这些难道不是常识吗? 你说的没错,但那些高手恰恰是将尝试变成了一种日常习惯去反复练习——因为“思维陷阱”会无时无刻存在,人必须通过训练保持觉知才行,所以我们需要复习一下这三种思维习惯: **1. 如何训练 ** 带着无知“观察”的思维习惯? 日常中,很多人会觉得自己的情商和同理心不足,不知道对方心里想什么,要怎么办? 这就可以先从“观察”自己的内心的练习开始。 练习“观察”的方式: 保持空无,抛下预设 ▼ 用客体视角觉察出自己内心与行为的关系 ▼ 再试着深入“阅读”他人内心与行为的关系 ▼ 结合规律,分析出外界真实的需要 ▼ 在生活与工作中做出策略调整或反应 ▼ 保持练习,达到情商和洞察力的提高 如果观察熟练,可以用这个方法去看世界和他人的情绪,进而搞明白对方真正的需要,即使是对方没有清晰表达出来的。 打个比方:春节时期,网上那种对于钟南山敬佩和对湖北一些事情愤怒的两极声音,如果你用心观察,你会发现他们的底层其实是同一种情绪“恐惧”——恐惧引发了行为,无论是愤怒还是寻找安全感。 再打个比方:如你单位中有一个人,别人都说这个人是自私自利的小人;你通过“观察”发现,原来对方只是个内心缺乏安全感的可怜人,所以也就可以在职场打交道中理解和推测出对方的想法和行为,读出对方真正的内心需要。 做市场运营,产品经理,品牌定位,尤其需要这种“观察”他人内心真正需要的能力。 **2. 如何训练 ** 保持“关联性”思考的习惯? 如何培养“关联性”思维,在职场拿到资源,产生更好的协作? 练习“关联性”思维的方式: 抛开过去那种任何事都想着“自己干”的想法,问自己三个问题: 我现在要做的事情,有没有利他性? 可以不可以与他人形成合力? 最终取得的成果,能不能多方共享? 如果三个问题想清楚了没问题,那么不怕拒绝,厚着脸皮干就完了! 如果三个问题想清楚了没问题,那么不怕拒绝,厚着脸皮干就完了! 日常要留心,自己和他人身上,有哪些可以“做成事”的资源,这并不是要人学会自利,而是需要培养自己的协作性;自己的专业知识,钱,甚至体力,时间,人脉圈,都是能一起互相协作的资源。 除了人与人的资源关联性,还可以培养物与物相互跨界联系的能力。 比如在阿里,训练公关的新闻策划能力,就有一种称之为“两只试管法”的日常思考方法。 你可以想象成左手握一个产品试管,右手握一个情绪试管,然后两种试剂倒在了一起,产生神奇的化学反应。 比如: 盒马鲜生(线下的果蔬生鲜服务设施/一种都市快节奏生活方式)+ 房价(情绪饱满的高敏感民生话题)= 品牌概念:盒区房 进口水果 + 北上广的生活压力(情绪饱满的消费焦虑)= 热门话题:车厘子自由 “关联性”思维练习配合“观察”运用在策划和创意里,是不是非常有趣? **3. 如何训练 ** “看穿事物底层矛盾”的思维习惯? 看事物的底层逻辑,也同样需要上面的两种思维。 日常可以多读读经典,少接触如今的“时髦概念书”以免被先入为主污染,枕头边可以放一本《毛选》,其中《矛盾论》和《实践论》是精华。 日常遇到争议性的事情,不要着急下判断,也不要站队;就站在旁观者的角度,思考思考为什么双方会这么想,他们各自有哪些需要没有被满足? 渐渐地,在别人眼中,你成了一开口就可以直击问题本质的人。 等到熟练之后,再拿来看一个人群或者一片市场,思考和实践调研他们真正的供需中,有哪些地方是目前供需所不平衡的,在这样不平衡产生的痛点中,出现了什么替代方案? 以上就是我所分享的练习方法。 最后补充一点:如果有一件事你觉得一定会如此,那么保险起见尝试从相反的方向推论看有没有漏洞。 你还可以经常对外分享自己的心得和观点(我自己就在用这种方式保持二次学习和修正提炼),不要担心出错,通过理性的交流和思辨,通过他人的认知进行思辨和修正。 通过这种方式收获了解,你会发现:自己其实并不孤独。 参考: 《毛选》 《行为》罗伯特·M·萨波斯基 《智能的结构》霍华德·加德纳 《硬球》克里斯·马修斯 《合作的进化》罗伯特.阿克塞尔罗德 《笑傲江湖》金庸 作者:舒扬,笔名舍予兄(个人WX:shuyang9451)休养前担任阿里健康高级公关专家,目前是一名 长跑 和 行为心理学 爱好者,著有畅销书《共鸣》,一个喜欢深夜在朋友圈发长篇思考的人。事业目标是成为最好的公关,在这条路上将永远是一个学生。
剑曼红尘 2020-04-13 11:47:20 0 浏览量 回答数 0

回答

mysql的聚簇索引是指innodb引擎的特性,mysiam并没有,如果需要该索引,只要将索引指定为主键(primary key)就可以了。比如:create table blog_user( user_Name char(15) not null check(user_Name !=''), user_Password char(15) not null, user_emial varchar(20) not null unique, primary key(user_Name) )engine=innodb default charset=utf8 auto_increment=1;其中的 primary key(user_Name) 这个就是聚簇索引索引了;聚簇索引的叶节点就是数据节点,而非聚簇索引的叶节点仍然是索引节点,并保留一个链接指向对应数据块。聚簇索引主键的插入速度要比非聚簇索引主键的插入速度慢很多。相比之下,聚簇索引适合排序,非聚簇索引(也叫二级索引)不适合用在排序的场合。因为聚簇索引本身已经是按照物理顺序放置的,排序很快。非聚簇索引则没有按序存放,需要额外消耗资源来排序。当你需要取出一定范围内的数据时,用聚簇索引也比用非聚簇索引好。另外,二级索引需要两次索引查找,而不是一次才能取到数据,因为存储引擎第一次需要通过二级索引找到索引的叶子节点,从而找到数据的主键,然后在聚簇索引中用主键再次查找索引,再找到数据。innodb索引分类:聚簇索引(clustered index)    1)  有主键时,根据主键创建聚簇索引    2)  没有主键时,会用一个唯一且不为空的索引列做为主键,成为此表的聚簇索引    3) 如果以上两个都不满足那innodb自己创建一个虚拟的聚集索引辅助索引(secondary index)   非聚簇索引都是辅助索引,像复合索引、前缀索引、唯一索引 myisam索引:因为myisam的索引和数据是分开存储存储的,myisam通过key_buffer把索引先缓存到内存中,当需要访问数据时(通过索引访问数据),在内存中直接搜索                         索引,然后通过索引找到磁盘相应数据,这也就是为什么索引不在key buffer命中时,速度慢的原因     innodb索引:innodb的数据和索引放在一起,当找到索引也就找到了数据 自适应哈希索引:innodb会监控表上的索引使用情况,如果观察到建立哈希索引可以带来速度的提升,那就建立哈希索引,自 适应哈希索引通过缓冲池的B+树构造而来,                               因此建立的速度很快,不需要将整个表都建哈希索引,InnoDB 存储引擎会自动根据访问的频率和模式来为某些页建立哈希索引。自适应哈希索引不需要                               存储磁盘的,当停库内容会丢失,数据库起来会自己创建,慢慢维护索引。     聚簇索引:MySQL InnoDB一定会建立聚簇索引,把实际数据行和相关的键值保存在一块,这也决定了一个表只能有一个聚簇索引,即MySQL不会一次把数据行保存在二个地方。     1)  InnoDB通常根据主键值(primary key)进行聚簇     2) 如果没有创建主键,则会用一个唯一且不为空的索引列做为主键,成为此表的聚簇索引     3) 上面二个条件都不满足,InnoDB会自己创建一个虚拟的聚集索引 优点:聚簇索引的优点,就是提高数据访问性能。聚簇索引把索引和数据都保存到同一棵B+树数据结构中,并且同时将索引列与相关数据行保存在一起。这意味着,当你访问同一数据页不同行记录时,已经把页加载到了Buffer中,再次访问的时候,会在内存中完成访问,不必访问磁盘。不同于MyISAM引擎,它将索引和数据没有放在一块,放在不同的物理文件中,索引文件是缓存在key_buffer中,索引对应的是磁盘位置,不得不通过磁盘位置访问磁盘数据。  缺点:1) 维护索引很昂贵,特别是插入新行或者主键被更新导至要分页(page split)的时候。建议在大量插入新行后,选在负载较低的时间段,通过OPTIMIZE TABLE优化表,因为必须被移动的行数据可能造成碎片。使用独享表空间可以弱化碎片   2) 表因为使用UUId作为主键,使数据存储稀疏,这就会出现聚簇索引有可能有比全表扫面更慢,所以建议使用int的auto_increment作为主键 3) 如果主键比较大的话,那辅助索引将会变的更大,因为辅助索引的叶子存储的是主键值;过长的主键值,会导致非叶子节点占用占用更多的物理空间  辅助索引在聚簇索引之上创建的索引称之为辅助索引,辅助索引访问数据总是需要二次查找。辅助索引叶子节点存储的不再是行的物理位置,而是主键值。通过辅助索引首先找到的是主键值,再通过主键值找到数据行的数据叶,再通过数据叶中的Page Directory找到数据行。复合索引由多列创建的索引称为符合索引,在符合索引中的前导列必须出现在where条件中,索引才会被使用ALTER TABLE test.users ADD INDEX idx_users_id_name (name(10) ASC, id ASC) ; 前缀索引当索引的字符串列很大时,创建的索引也就变得很大,为了减小索引体积,提高索引的扫描速度,就用索引的前部分字串索引,这样索引占用的空间就会大大减少,并且索引的选择性也不会降低很多。而且是对BLOB和TEXT列进行索引,或者非常长的VARCHAR列,就必须使用前缀索引,因为MySQL不允许索引它们的全部长度。使用:列的前缀的长度选择很重要,又要节约索引空间,又要保证前缀索引的选择性要和索引全长度选择性接近。 唯一索引唯一索引比较好理解,就是索引值必须唯一,这样的索引选择性是最好的 主键索引主键索引就是唯一索引,不过主键索引是在创建表时就创建了,唯一索引可以随时创建。说明主键和唯一索引区别     1) 主键是主键约束+唯一索引     2) 主键一定包含一个唯一索引,但唯一索引不是主键     3) 唯一索引列允许空值,但主键列不允许空值     4) 一个表只能有一个主键,但可以有多个唯一索引 索引扫描方式:紧凑索引扫描(dense index):在最初,为了定位数据需要做权表扫描,为了提高扫描速度,把索引键值单独放在独立的数据的数据块里,并且每个键值都有个指向原数据块的指针,因为索引比较小,扫描索引的速度就比扫描全表快,这种需要扫描所有键值的方式就称为紧凑索引扫描 松散索引扫描(sparse index):为了提高紧凑索引扫描效率,通过把索引排序和查找算法(B+trre),发现只需要和每个数据块的第一行键值匹配,就可以判断下一个数据块的位置或方向,因此有效数据就是每个数据块的第一行数据,如果把每个数据块的第一行数据创建索引,这样在这个新创建的索引上折半查找,数据定位速度将更快。这种索引扫描方式就称为松散索引扫描。 覆盖索引扫描(covering index):包含所有满足查询需要的数据的索引称为覆盖索引,即利用索引返回select列表中的字段,而不必根据索引再次读取数据文件索引相关常用命令:1) 创建主键 CREATE TABLE pk_tab2 (  id int(11) NOT NULL AUTO_INCREMENT,  a1 varchar(45) DEFAULT NULL,  PRIMARY KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8; 2) 创建唯一索引create unique index indexname on tablename(columnname); alter table tablename add unique index indexname(columnname); 3) 创建单列一般索引create index indexname on tablename(columnname);alter table tablename add index indexname(columnname); 4) 创建单列前缀索引create index indexname on tablename(columnname(10));    //单列的前10个字符创建前缀索引alter table tablename add index indexname(columnname(10)); //单列的前10个字符创建前缀索引 5) 创建复合索引create index indexname on tablename(columnname1,columnname2);    //多列的复合索引create index indexname on tablename(columnname1,columnname2(10));    //多列的包含前缀的复合索引alter table tablename add index indexname(columnname1,columnname2); //多列的复合索引alter table tablename add index indexname(columnname1,columnname(10)); //多列的包含前缀的复合索引 6) 删除索引drop index indexname on tablename;;alter table tablename drop  index indexname; 7) 查看索引show index from tablename;show create table pk_tab2;作者:大树叶 来源:CSDN 原文:https://blog.csdn.net/bigtree_3721/article/details/51335479 版权声明:本文为博主原创文章,转载请附上博文链接!
孟志昂 2019-12-02 01:45:11 0 浏览量 回答数 0

问题

拓扑排序 7月5日 【今日算法】

前言 Topological sort 又称 Topological order,这个名字有点迷惑性,因为拓扑排序并不是一个纯粹的排序算法,它只是针对某一类图,找到一个可以执行的线性...
游客ih62co2qqq5ww 2020-07-07 09:48:17 19 浏览量 回答数 1

问题

备战大厂每日挑战算法,坚持打卡更有社区定制周边奖品等你赢!

算法工程师,一个听起来非常高大上的职业~ 不但轻轻松松月入过万,更是进入大厂必考的题目。如何通过大厂算法岗面试?如何轻轻松松拿到高薪?如何成为算法技术大牛? 今天开发者...
被纵养的懒猫 2020-04-07 11:41:45 5309 浏览量 回答数 5

问题

【阿里云产品公测】简单日志服务SLS使用评测含教程

评测介绍 被测产品: 简单日志服务SLS评测环境: 阿里云基础ECS x2(1核, 512M, 1M)操作系统: CentOS 6.5 x64日志环境: Nginx(v1.6.2) HTTP服务器访问日志评测人: mr_wid评测时间...
mr_wid 2019-12-01 21:08:11 36639 浏览量 回答数 20

回答

Java之JVM垃圾回收 内存结构以及垃圾回收算法前言:由于小组技术分享的需要,懂的不是很多所以我就找了这个我自己感兴趣的知识点给大家做个简单的介绍。由于是新人,算不了很懂,只是总结性的讲了些概念性的东西。给大家分享的同时,算是给自己做个笔记吧。作为Java语言的核心之一,JVM垃圾回收帮我们解决了让我们很头疼的垃圾回收问题。我们不需要像VC++一样,作为内存管理的统治者需要我们对我们分配的每一块内存进行回收,否则就会造成内存泄露问题。是不是只要有JVM存在我们就不会出现内存泄露问题,出现内存泄露问题我们又该怎么办,如果我们想提高我们程序的稳定性和其他性能我们能从什么地方下手!!!相信这些问题是我们程序过程中不可逾越的。了解JVM的内存分配及其相应的垃圾回收机制,不仅仅是可以了解底层的JVM运行机制,而且对于程序性能的优化和提升还是很有必要的。一、JVM内存分配区域结构图一从图一可以看出JVM中的内存分配包括PC Register(PC寄存器) JVM栈 堆(Heap) 方法区域(MethodArea)运行时常量池(RuntimeConstant Pool) 本地方法堆栈(NativeMethod Stacks),这几部分区域但是从程序员的角度来看我们只关注JVM Heap和JVM Stack,因为这两部分是直接关系程序运行期间的内存状态,所以我会主要介绍这两部分内存,其他的我只是给出了简单的一些概念性解释:PC Register(Program Counter 寄存器):主要作用是记录当前线程所执行的字节码的行号。方法区域(MethodArea):方法区域存放了所加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义为final类型的常量、类中的Field信息、类中的方法信息,法区域也是全局共享的,它在虚拟机启动时在一定的条件下它也会被GC,当方法区域需要使用的内存超过其允许的大小时,会抛出OutOfMemory的错误信息。运行时常量池(RuntimeConstant Pool):存放的为类中的固定的常量信息、方法和Field的引用信息等,其空间从方法区域中分配。本地方法堆栈(NativeMethod Stacks):JVM采用本地方法堆栈来支持native方法的执行,此区域用于存储每个native方法调用的状态。JVM栈:主要存放一些基本类型的变量和对象的引用变量。JVM堆:用来存放由 new 创建的对象和数组Java 虚拟机的自动垃圾回收器来管理(注意数组也是对象,所以说数组也是存放在JVM堆中)。由于栈中存放的是主要存放一些基本类型的变量和对象的引用变量,所以当过了变量的作用区域或者是当程序运行结束后它所占用的内存会自动的释放掉,所以不用来关心,下面我们主要来说的是堆内存的分配以及回收的算法。二、JVM堆内存介绍工欲善其事,必先利其器。所以了解堆内存的内部结构是很必要的。在Jvm中堆空间划分为三个代:年轻代(Young Generation)、年老代(Old Generation)和永久代(Permanent Generation)。年轻带主要是动态的存储,年轻带主要储存新产生的对象,年老代储存年龄大些的对象,永久带主要是存储的是java的类信息,包括解析得到的方法、属性、字段等。永久带基本不参与垃圾回收。所以说我们说的垃圾回收主要是针对年轻代和年老代。图二年轻代又分成3个部分,一个eden区和两个相同的survior区。刚开始创建的对象都是放置在eden区的。分成这样3个部分,主要是为了生命周期短的对象尽量留在年轻带。当eden区申请不到空间的时候,进行minorGC,把存活的对象拷贝到survior。年老代主要存放生命周期比较长的对象,比如缓存对象。(经过IBM的一个研究机构研究数据表明,基本上80%-98%的对象都会在年轻代的Eden区死掉从而本回收掉,所以说真正进入到老年代的对象很少,这也是为什么MinorGC比MajorGC更加频繁的原因)具体JVM内存垃圾回收过程描述如下 :1、对象在Eden区完成内存分配2、当Eden区满了,再创建对象,会因为申请不到空间,触发minorGC,进行young(eden+1survivor)区的垃圾回收3、minorGC时,Eden不能被回收的对象被放入到空的survivor(Eden肯定会被清空),另一个survivor里不能被GC回收的对象也会被放入这个survivor,始终保证一个survivor是空的4、当做第3步的时候,如果发现survivor满了,则这些对象被copy到old区,或者survivor并没有满,但是有些对象已经足够Old,也被放入Old区 XX:MaxTenuringThreshold5、当Old区被放满的之后,进行fullGC补充: MinorGC:年轻代所进行的垃圾回收,非常频繁,一般回收速度也比较快。 MajorGC:老年代进行的垃圾回收,发生一次MajorGC至少伴随一次MinorGC,一般比MinorGC速度慢十倍以上。 FullGC:整个堆内存进行的垃圾回收,很多时候是MajorGC 以后就是堆内存结构已经大致的垃圾回收过程。三、对象分配原则1.对象优先分配在Eden区,如果Eden区没有足够的空间时,虚拟机执行一次Minor GC。2.大对象直接进入老年代(大对象是指需要大量连续内存空间的对象)。这样做的目的是避免在Eden区和两个Survivor区之间发生大量的内存拷贝(新生代采用复制算法收集内存)。3.长期存活的对象进入老年代。虚拟机为每个对象定义了一个年龄计数器,如果对象经过了1次Minor GC那么对象会进入Survivor区,之后每经过一次Minor GC那么对象的年龄加1,知道达到阀值对象进入老年区。4.动态判断对象的年龄。如果Survivor区中相同年龄的所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代。5.空间分配担保。每次进行Minor GC时,JVM会计算Survivor区移至老年区的对象的平均大小,如果这个值大于老年区的剩余值大小则进行一次Full GC,如果小于检查HandlePromotionFailure设置,如果true则只进行Monitor GC,如果false则进行Full GC。四、垃圾收集器作为JVM中的核心之一垃圾收集器,主要完成的功能包括:(1)发现无用信息对象;(2)回收被无用对象占用的内存空间,使该空间可被程序再次使用。所以说我们在实现垃圾收集器的同时就要实现两个算法一个是发现无用的对象第二就是回收该对象的内存。收集器主要分为引用计数器和跟踪收集器两种,Sun JDK中采用跟踪收集器作为GC实现策略。发现无用对象只要的实现算法包括引用计数法和根搜索算法,引用计数法主要是JVM的早期实现方法,因为引用计数无法解决循环引用的问题,所以现在JVM实现的主要是根搜索算法,引用计数法:堆中的每个对象对应一个引用计数器。当每一次创建一个对象并赋给一个变量时,引用计数器置为1。当对象被赋给任意变量时,引用计数器每次加1当对象出了作用域后(该对象丢弃不再使用),引用计数器减1,一旦引用计数器为0,对象就不可用从而可以被回收。 根搜索算法:通过一系列的名为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连(用图论的话来说就是从GC Roots到这个对象不可达)时,则证明此对象是不可用的。目前的收集器主要有三种:串行收集器:使用单线程处理所有垃圾回收工作,因为无需多线程交互,所以效率比较高并行收集器:对年轻代进行并行垃圾回收,因此可以减少垃圾回收时间。一般在多线程多处理器机器上使用并发收集器:可以保证大部分工作都并发进行(应用不停止),垃圾回收只暂停很少的时间,此收集器适合对响应时间要求比较高的中、大规模应用五、垃圾收集器的回收算法Copying算法:算法:复制采用的方式为从根集合扫描出存活的对象,并将找到的存活对象复制到一块新的完全未使用的空间中。 过程: 此算法把内存空间划为两个相等的区域,每次只使用其中一个区域。垃圾回收时,遍历当前使用区域,把正在使用中的对象复制到另外一个区域中。次算法每次只处理正在使用中的对象,因此复制成本比较小,同时复制过去以后还能进行相应的内存整理,不过出现“碎片”问题。当然,此算法的缺点也是很明显的,就是需要两倍内存空间。Mark-Sweep算法: 算法:标记-清除采用的方式为从根集合开始扫描,对存活的对象进行标记,标记完毕后,再扫描整个空间中未标记的对象,并进行回收。 过程: 第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除。它停止所有工作,收集器从根开始访问每一个活跃的节点,标记它所访问的每一个节点。走过所有引用后,收集就完成了,然后就对堆进行清除(即对堆中的每一个对象进行检查),所有没有标记的对象都作为垃圾回收并返回空闲列表。Mark-Compact算法: 算法:标记阶段与“Mark-Sweep”算法相同,但在清除阶段有所不同。在回收不存活对象所占用的内存空间后,会将其他所有存活对象都往左端空闲的空间进行移动,并更新引用其对象指针。过程:此算法结合了“标记-清除”和“复制”两个算法的优点。也是分两阶段,第一阶段从根节点开始标记所有被引用对象,第二阶段遍历整个堆,把清除未标记对象并且把存活对象“压缩”到堆的其中一块,按顺序排放。此算法避免了“标记-清除”的碎片问题,同时也避免了“复制”算法的空间问题。Sun JDK GC策略:新生代算法实现:Copying,Copying,Copying旧生代算发实现:Mark-Sweep-Compact,Mark –Compact,Mark –Sweep!!六、JvisuaVM 工具如果我们想优化自己的程序,那么我们就必须清楚的了解不同代码程序所消耗的性能多少,作为JDK的一部分,这个工具给我们提供了很大的帮助。这个工具可以在JDK的bin目录下找到,功能很强大,可以注意利用
auto_answer 2019-12-02 01:56:35 0 浏览量 回答数 0

问题

OpenSearch的搜索处理是什么?

Search 搜索 系统提供了丰富的搜索语法以满足用户各种场景下的搜索需求。 URL /v3/openapi/apps/$app_name/search?fetch_fields=name&query=c...
轩墨 2019-12-01 20:57:06 1661 浏览量 回答数 0

问题

【算法】五分钟算法小知识:二叉堆详解实现优先级队列

二叉堆(Binary Heap)没什么神秘,性质比二叉搜索树 BST 还简单。其主要操作就两个,sink(下沉)和 swim(上浮࿰...
游客ih62co2qqq5ww 2020-05-12 16:17:02 4 浏览量 回答数 1

问题

云效产品【Q&amp;A】一览表②

五、接口自动化(SAT) Q1:接口自动化中项目用例中没有HTTP接口? A1:目前只有调试用例和主干用例支持HTTP。 Q2:接口自动化中数...
云效平台 2019-12-01 22:10:09 3021 浏览量 回答数 0

问题

图解!24张图彻底弄懂九大常见数据结构! 7月22日 【今日算法】

数据结构想必大家都不会陌生,对于一个成熟的程序员而言,熟悉和掌握数据结构和算法也是基本功之一。数据结构本身其实不过是数据按照特点关系进行存储或者组织的集合,特殊的结构在不同的应用场景中往往会带来不一...
游客ih62co2qqq5ww 2020-07-27 13:19:32 6 浏览量 回答数 1

回答

请参考个人博客:https://blog.csdn.net/u010870518/article/details/79450295 在进一步分析为什么MySQL数据库索引选择使用B+树之前,我相信很多小伙伴对数据结构中的树还是有些许模糊的,因此我们由浅入深一步步探讨树的演进过程,在一步步引出B树以及为什么MySQL数据库索引选择使用B+树! 学过数据结构的一般对最基础的树都有所认识,因此我们就从与我们主题更为相近的二叉查找树开始。 一、二叉查找树 (1)二叉树简介: 二叉查找树也称为有序二叉查找树,满足二叉查找树的一般性质,是指一棵空树具有如下性质: 1、任意节点左子树不为空,则左子树的值均小于根节点的值; 2、任意节点右子树不为空,则右子树的值均大于于根节点的值; 3、任意节点的左右子树也分别是二叉查找树; 4、没有键值相等的节点; 上图为一个普通的二叉查找树,按照中序遍历的方式可以从小到大的顺序排序输出:2、3、5、6、7、8。 对上述二叉树进行查找,如查键值为5的记录,先找到根,其键值是6,6大于5,因此查找6的左子树,找到3;而5大于3,再找其右子树;一共找了3次。如果按2、3、5、6、7、8的顺序来找同样需求3次。用同样的方法在查找键值为8的这个记录,这次用了3次查找,而顺序查找需要6次。计算平均查找次数得:顺序查找的平均查找次数为(1+2+3+4+5+6)/ 6 = 3.3次,二叉查找树的平均查找次数为(3+3+3+2+2+1)/6=2.3次。二叉查找树的平均查找速度比顺序查找来得更快。 (2)局限性及应用 一个二叉查找树是由n个节点随机构成,所以,对于某些情况,二叉查找树会退化成一个有n个节点的线性链。如下图: 大家看上图,如果我们的根节点选择是最小或者最大的数,那么二叉查找树就完全退化成了线性结构。上图中的平均查找次数为(1+2+3+4+5+5)/6=3.16次,和顺序查找差不多。显然这个二叉树的查询效率就很低,因此若想最大性能的构造一个二叉查找树,需要这个二叉树是平衡的(这里的平衡从一个显著的特点可以看出这一棵树的高度比上一个输的高度要大,在相同节点的情况下也就是不平衡),从而引出了一个新的定义-平衡二叉树AVL。 二、AVL树 (1)简介 AVL树是带有平衡条件的二叉查找树,一般是用平衡因子差值判断是否平衡并通过旋转来实现平衡,左右子树树高不超过1,和红黑树相比,它是严格的平衡二叉树,平衡条件必须满足(所有节点的左右子树高度差不超过1)。不管我们是执行插入还是删除操作,只要不满足上面的条件,就要通过旋转来保持平衡,而旋转是非常耗时的,由此我们可以知道AVL树适合用于插入删除次数比较少,但查找多的情况。 从上面是一个普通的平衡二叉树,这张图我们可以看出,任意节点的左右子树的平衡因子差值都不会大于1。 (2)局限性 由于维护这种高度平衡所付出的代价比从中获得的效率收益还大,故而实际的应用不多,更多的地方是用追求局部而不是非常严格整体平衡的红黑树。当然,如果应用场景中对插入删除不频繁,只是对查找要求较高,那么AVL还是较优于红黑树。 (3)应用 1、Windows NT内核中广泛存在; 三、红黑树 (1)简介 一种二叉查找树,但在每个节点增加一个存储位表示节点的颜色,可以是red或black。通过对任何一条从根到叶子的路径上各个节点着色的方式的限制,红黑树确保没有一条路径会比其它路径长出两倍。它是一种弱平衡二叉树(由于是若平衡,可以推出,相同的节点情况下,AVL树的高度低于红黑树),相对于要求严格的AVL树来说,它的旋转次数变少,所以对于搜索、插入、删除操作多的情况下,我们就用红黑树。 (2)性质 1、每个节点非红即黑; 2、根节点是黑的; 3、每个叶节点(叶节点即树尾端NULL指针或NULL节点)都是黑的; 4、如果一个节点是红的,那么它的两儿子都是黑的; 5、对于任意节点而言,其到叶子点树NULL指针的每条路径都包含相同数目的黑节点; 6、每条路径都包含相同的黑节点; (3)应用 1、广泛用于C++的STL中,Map和Set都是用红黑树实现的; 2、著名的Linux进程调度Completely Fair Scheduler,用红黑树管理进程控制块,进程的虚拟内存区域都存储在一颗红黑树上,每个虚拟地址区域都对应红黑树的一个节点,左指针指向相邻的地址虚拟存储区域,右指针指向相邻的高地址虚拟地址空间; 3、IO多路复用epoll的实现采用红黑树组织管理sockfd,以支持快速的增删改查; 4、Nginx中用红黑树管理timer,因为红黑树是有序的,可以很快的得到距离当前最小的定时器; 5、Java中TreeMap的实现; 四、B/B+树 说了上述的三种树:二叉查找树、AVL和红黑树,似乎我们还没有摸到MySQL为什么要使用B+树作为索引的实现,不要急,接下来我们就先探讨一下什么是B树。 (1)简介 我们在MySQL中的数据一般是放在磁盘中的,读取数据的时候肯定会有访问磁盘的操作,磁盘中有两个机械运动的部分,分别是盘片旋转和磁臂移动。盘片旋转就是我们市面上所提到的多少转每分钟,而磁盘移动则是在盘片旋转到指定位置以后,移动磁臂后开始进行数据的读写。那么这就存在一个定位到磁盘中的块的过程,而定位是磁盘的存取中花费时间比较大的一块,毕竟机械运动花费的时候要远远大于电子运动的时间。当大规模数据存储到磁盘中的时候,显然定位是一个非常花费时间的过程,但是我们可以通过B树进行优化,提高磁盘读取时定位的效率。 为什么B类树可以进行优化呢?我们可以根据B类树的特点,构造一个多阶的B类树,然后在尽量多的在结点上存储相关的信息,保证层数尽量的少,以便后面我们可以更快的找到信息,磁盘的I/O操作也少一些,而且B类树是平衡树,每个结点到叶子结点的高度都是相同,这也保证了每个查询是稳定的。 总的来说,B/B+树是为了磁盘或其它存储设备而设计的一种平衡多路查找树(相对于二叉,B树每个内节点有多个分支),与红黑树相比,在相同的的节点的情况下,一颗B/B+树的高度远远小于红黑树的高度(在下面B/B+树的性能分析中会提到)。B/B+树上操作的时间通常由存取磁盘的时间和CPU计算时间这两部分构成,而CPU的速度非常快,所以B树的操作效率取决于访问磁盘的次数,关键字总数相同的情况下B树的高度越小,磁盘I/O所花的时间越少。 注意B-树就是B树,-只是一个符号。 (2)B树的性质 1、定义任意非叶子结点最多只有M个儿子,且M>2; 2、根结点的儿子数为[2, M]; 3、除根结点以外的非叶子结点的儿子数为[M/2, M]; 4、每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字) 5、非叶子结点的关键字个数=指向儿子的指针个数-1; 6、非叶子结点的关键字:K[1], K[2], …, K[M-1];且K[i] < K[i+1]; 7、非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树; 8、所有叶子结点位于同一层; 这里只是一个简单的B树,在实际中B树节点中关键字很多的,上面的图中比如35节点,35代表一个key(索引),而小黑块代表的是这个key所指向的内容在内存中实际的存储位置,是一个指针。 五、B+树 (1)简介 B+树是应文件系统所需而产生的一种B树的变形树(文件的目录一级一级索引,只有最底层的叶子节点(文件)保存数据)非叶子节点只保存索引,不保存实际的数据,数据都保存在叶子节点中,这不就是文件系统文件的查找吗? 我们就举个文件查找的例子:有3个文件夹a、b、c, a包含b,b包含c,一个文件yang.c,a、b、c就是索引(存储在非叶子节点), a、b、c只是要找到的yang.c的key,而实际的数据yang.c存储在叶子节点上。 所有的非叶子节点都可以看成索引部分! (2)B+树的性质(下面提到的都是和B树不相同的性质) 1、非叶子节点的子树指针与关键字个数相同; 2、非叶子节点的子树指针p[i],指向关键字值属于[k[i],k[i+1]]的子树.(B树是开区间,也就是说B树不允许关键字重复,B+树允许重复); 3、为所有叶子节点增加一个链指针; 4、所有关键字都在叶子节点出现(稠密索引). (且链表中的关键字恰好是有序的); 5、非叶子节点相当于是叶子节点的索引(稀疏索引),叶子节点相当于是存储(关键字)数据的数据层; 6、更适合于文件系统; 非叶子节点(比如5,28,65)只是一个key(索引),实际的数据存在叶子节点上(5,8,9)才是真正的数据或指向真实数据的指针。 (3)应用 1、B和B+树主要用在文件系统以及数据库做索引,比如MySQL; 六、B/B+树性能分析 n个节点的平衡二叉树的高度为H(即logn),而n个节点的B/B+树的高度为logt((n+1)/2)+1;   若要作为内存中的查找表,B树却不一定比平衡二叉树好,尤其当m较大时更是如此。因为查找操作CPU的时间在B-树上是O(mlogtn)=O(lgn(m/lgt)),而m/lgt>1;所以m较大时O(mlogtn)比平衡二叉树的操作时间大得多。因此在内存中使用B树必须取较小的m。(通常取最小值m=3,此时B-树中每个内部结点可以有2或3个孩子,这种3阶的B-树称为2-3树)。 七、为什么说B+树比B树更适合数据库索引? 1、 B+树的磁盘读写代价更低:B+树的内部节点并没有指向关键字具体信息的指针,因此其内部节点相对B树更小,如果把所有同一内部节点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多,一次性读入内存的需要查找的关键字也就越多,相对IO读写次数就降低了。 2、B+树的查询效率更加稳定:由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。 3、由于B+树的数据都存储在叶子结点中,分支结点均为索引,方便扫库,只需要扫一遍叶子结点即可,但是B树因为其分支结点同样存储着数据,我们要找到具体的数据,需要进行一次中序遍历按序来扫,所以B+树更加适合在区间查询的情况,所以通常B+树用于数据库索引。 PS:我在知乎上看到有人是这样说的,我感觉说的也挺有道理的: 他们认为数据库索引采用B+树的主要原因是:B树在提高了IO性能的同时并没有解决元素遍历的我效率低下的问题,正是为了解决这个问题,B+树应用而生。B+树只需要去遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作或者说效率太低。 ———————————————— 版权声明:本文为CSDN博主「徐刘根」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/u010870518/java/article/details/79450295
AA大大官 2020-03-31 14:54:01 0 浏览量 回答数 0

回答

以前上网很快,最近1周网速突然很慢,我是3个人共用一个路由器的,以前3个人用时也是很快。现在是我看视频很卡,用了优化大师优化,c盘文件及桌面文件都清理了,用360也清理了垃圾文件,用小红伞杀毒也没杀出病毒,就是老样子。现在两个人用一个,也是很慢,到半夜了在搜狐视频或是酷六什么那看电影,只剩我一个人在用,还是卡。 请问高手能帮我诊断下怎么回事,或是怎么设置下改变下状况。另一个人也是发现网速慢了,我们都是一个样子,可能是被盗了吗? 我用360查看网络连接,system id process 的连接很多,显示是没有连接上,状态是等待,都是端口80,目标归属地什么北京联通,大连联通,深圳联通的,有7个左右,我qq也没开啊,想结束也结束不了,只是在迅雷看看里看电影,没有装他的插件。把它关了还是有。向高手请教?插件只有搜狗输入法,迅雷,360,迅雷看看没有其他的 " 网速变慢的原因有很多可能,比如网络本身的问题、网卡硬件问题,有或者是系统问题等等。可以通过其他联网设备确认下是否有网速变慢的情况;如果网络本身没有问题(其他设备可以正常连接),问题就出现电脑本身: 1,、疑难解答 可以先试试更新网卡驱动,若无效,我们可以利用系统自身提供的【疑难解答】功能来寻求解决。直接搜索进入【疑难解答】然后点击右侧的对应项目,选择【运行疑难解答】,按照向导提示进行操作即可,看是否能够解决网络连接问题。 <img src=""https://gss0.baidu.com/-fo3dSag_xI4khGko9WTAnF6hhy/zhidao/wh%3D600%2C800/sign=f415cd6cda3f8794d3aa4028e22b22cc/a6efce1b9d16fdfac901e83aba8f8c5495ee7bf0.jpg""> <img src=""https://gss0.baidu.com/-Po3dSag_xI4khGko9WTAnF6hhy/zhidao/wh%3D600%2C800/sign=1695c9ff00f41bd5da06e0f261eaadf3/f2deb48f8c5494ee9b9421cd23f5e0fe98257eab.jpg""> 2、网络重置 上述均不能解决的话,最后可通过进行网络重置来彻底解决。路径:【开始】—【设置】—【网络和Internet】—【状态】,在右侧列表中找到【网络重置】并点击,按提示完成操作即可。 <img src=""https://gss0.baidu.com/-Po3dSag_xI4khGko9WTAnF6hhy/zhidao/wh%3D600%2C800/sign=e6034daa9c58d109c4b6a1b4e168e087/11385343fbf2b211a844ab9ac48065380dd78eff.jpg""> 另外,在有限的硬件条件下,想让现有的网速能够快一些,具体可以参考以下步骤: 步骤1. Win+R组合键后输入gpedit.msc进入组策略编辑器,依次进入“计算机配置-Windows设置”后,再右侧找到“基于策略的Qos”的这个选项。 <img src=""https://gss0.baidu.com/-Po3dSag_xI4khGko9WTAnF6hhy/zhidao/wh%3D600%2C800/sign=c08ee009a564034f0f98ca009ff35509/a71ea8d3fd1f41341c7f2baa2b1f95cad0c85e9d.jpg""> 步骤2. 在“基于策略的Qos”上点击鼠标右键,选择“高级QoS设置”,在入站TCP流量选项卡中,勾选”制定入站TCP吞吐量级别“,选择最后那个”级别3“。 <img src=""https://gss0.baidu.com/9fo3dSag_xI4khGko9WTAnF6hhy/zhidao/wh%3D600%2C800/sign=f340223fb8fd5266a77e34129b28bb13/e1fe9925bc315c604623453b83b1cb13485477ab.jpg""> 注意的:如果在更改完设置后发现上网时系统出现假死、卡顿等问题,可以把上面的“制定入站TCP吞吐量级别“设置调整到“级别2”,减少数据处理对系统硬件的压力(内存小于4GB,则建议使用默认最小吞吐量)。 “高级QoS设置“是什么呢? 通过高级服务质量 (QoS) 设置,您可以管理带宽使用以及计算机处理应用程序和服务设置的 DSCP 标记(而不是组策略设置的标记)的方式。高级 QoS 设置仅可在计算机级别应用,而 QoS 策略在计算机级别和用户级别均可应用。 若要更改吞吐量级别,选中“指定入站 TCP 吞吐量级别”复选框,然后根据下表选择吞吐量级别。吞吐量级别可以等于或小于最大值,具体取决于网络条件。 <img src=""https://gss0.baidu.com/9vo3dSag_xI4khGko9WTAnF6hhy/zhidao/wh%3D600%2C800/sign=eea0cfe33bfae6cd0ce1a3673f83231c/ca1349540923dd542fc589bcdf09b3de9d8248ab.jpg"">" 一、网络自身问题 您想要连接的目标网站所在的服务器带宽不足或负载过大。处理办法很简单,请换个时间段再上或者换个目标网站。 二、网线问题导致网速变慢 我们知道,双绞线是由四对线按严格的规定紧密地绞和在一起的,用来减少串扰和背景噪音的影响。同时,在T568A标准和T568B标准中仅使用了双绞线的 1、2和3、6四条线,其中,1、2用于发送,3、6用于接收,而且1、2必须来自一个绕对,3、6必须来自一个绕对。只有这样,才能最大限度地避免串扰,保证数据传输。本人在实践中发现不按正确标准(T586A、T586B)制作的网线,存在很大的隐患。表现为:一种情况是刚开始使用时网速就很慢;另一种情况则是开始网速正常,但过了一段时间后,网速变慢。后一种情况在台式电脑上表现非常明显,但用笔记本电脑检查时网速却表现为正常。对于这一问题本人经多年实践发现,因不按正确标准制作的网线引起的网速变慢还同时与网卡的质量有关。一般台式计算机的网卡的性能不如笔记本电脑的,因此,在用交换法排除故障时,使用笔记本电脑检测网速正常并不能排除网线不按标准制作这一问题的存在。我们现在要求一律按T586A、T586B标准来压制网线,在检测故障时不能一律用笔记本电脑来代替台式电脑。 三、网络中存在回路导致网速变慢 当网络涉及的节点数不是很多、结构不是很复杂时,这种现象一般很少发生。但在一些比较复杂的网络中,经常有多余的备用线路,如无意间连上时会构成回路。比如网线从网络中心接到计算机一室,再从计算机一室接到计算机二室。同时从网络中心又有一条备用线路直接连到计算机二室,若这几条线同时接通,则构成回路,数据包会不断发送和校验数据,从而影响整体网速。这种情况查找比较困难。为避免这种情况发生,要求我们在铺设网线时一定养成良好的习惯:网线打上明显的标签,有备用线路的地方要做好记载。当怀疑有此类故障发生时,一般采用分区分段逐步排除的方法。 四、网络设备硬件故障引起的广播风暴而导致网速变慢 作为发现未知设备的主要手段,广播在网络中起着非常重要的作用。然而,随着网络中计算机数量的增多,广播包的数量会急剧增加。当广播包的数量达到30%时,网络的传输效率将会明显下降。当网卡或网络设备损坏后,会不停地发送广播包,从而导致广播风暴,使网络通信陷于瘫痪。因此,当网络设备硬件有故障时也会引起网速变慢。当怀疑有此类故障时,首先可采用置换法替换集线器或交换机来排除集线设备故障。如果这些设备没有故障,关掉集线器或交换机的电源后,DOS下用 “Ping”命令对所涉及计算机逐一测试,找到有故障网卡的计算机,更换新的网卡即可恢复网速正常。网卡、集线器以及交换机是最容易出现故障引起网速变慢的设备。 五、网络中某个端口形成了瓶颈导致网速变慢 实际上,路由器广域网端口和局域网端口、交换机端口、集线器端口和服务器网卡等都可能成为网络瓶颈。当网速变慢时,我们可在网络使用高峰时段,利用网管软件查看路由器、交换机、服务器端口的数据流量;也可用 Netstat命令统计各个端口的数据流量。据此确认网络数据流通瓶颈的位置,设法增加其带宽。具体方法很多,如更换服务器网卡为100M或1000M、安装多个网卡、划分多个VLAN、改变路由器配置来增加带宽等,都可以有效地缓解网络瓶颈,可以最大限度地提高数据传输速度。 六、蠕虫病毒的影响导致网速变慢 通过E-mail散发的蠕虫病毒对网络速度的影响越来越严重,危害性极大。这种病毒导致被感染的用户只要一上网就不停地往外发邮件,病毒选择用户个人电脑中的随机文档附加在用户机子的通讯簿的随机地址上进行邮件发送。成百上千的这种垃圾邮件有的排着队往外发送,有的又成批成批地被退回来堆在服务器上。造成个别骨干互联网出现明显拥塞,网速明显变慢,使局域网近于瘫痪。因此,我们必须及时升级所用杀毒软件;计算机也要及时升级、安装系统补丁程序,同时卸载不必要的服务、关闭不必要的端口,以提高系统的安全性和可靠性。 七、防火墙的过多使用 防火墙的过多使用也可导致网速变慢,处理办法不必多说,卸载下不必要的防火墙只保留一个功能强大的足以。 八、系统资源不足 您可能加载了太多的运用程序在后台运行,请合理的加载软件或删除无用的程序及文件,将资源空出,以达到提高网速的目的。 您好,如您的宽带出现故障,可关注“中国联通”微信公众号,点击“客户服务>宽带报障>常见故障指引”,查看对应故障的处理方式。 如仍无法解决,可通过以下方式自助报障: 【方式一】关注“中国联通”微信公众号,点击“客户服务>宽带报障>在线报障”; 【方式二】登录中国联通手机营业厅APP,点击“服务>宽带>宽带办理服务>宽带报障”。 1...用360安全卫士查一下启动项,可能是垃圾插件太多了。现在P2P插件很吸血的。优化一下。 2...把3台电脑恢复系统,还有问题就是线路的问题了。 你把路由器 关掉重启 或者 重装 网卡驱动 试试吧。 最好还是重装。 重装还不好使 就是 宽带问题。
保持可爱mmm 2019-12-02 02:14:41 0 浏览量 回答数 0

问题

图解九大数据结构 6月13日 【今日算法】

数据结构想必大家都不会陌生,对于一个成熟的程序员而言,熟悉和掌握数据结构和算法也是基本功之一。数据结构本身其实不过是数据按照特点关系进行存储或者组织的集合,特殊的结构在不同的应用场景中往往会带来不一...
游客ih62co2qqq5ww 2020-06-17 13:17:00 29 浏览量 回答数 1

问题

厉华:写一个开源容器引擎会是什么样的体验? 热:报错

2013年,Docker.Inc 开源了一款应用容器引擎 Docker。开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到相同内核的任何 Linux 机器上部署运行。这种集装箱式的应用开发和部署方...
kun坤 2020-06-10 10:01:12 3 浏览量 回答数 1

回答

不良的编程习惯TOP1:粘贴复制 在学生时代,我们都知道抄袭是不对的。但在工作中,这方面的规则还很模糊。虽然有些代码块是不能盗用的——不要把专有代码拷贝到你的堆栈中,尤其是这些代码有标记版权信息。这种时候你应该编写自己的版本,老板付你薪水就是要做正事的。 但是当原始创作者想要共享代码时,问题就变得复杂了。这些共享代码也许放到了某个在线编程论坛上,也许它们是带有许可证(BSD,MIT)的开放源代码,允许使用一到三个函数。你使用这些共享代码是没有问题的,而且你上班是为了解决问题,而不是重新发明轮子。 大多数情况下,复制代码的优势非常明显,小心对待的话问题也不大。至少那些从靠谱的来源获得的代码已经被大致“检查“过了。 问题的复杂之处在于,这些共享代码是否存在一些未发现的错误,代码的用途或底层数据是否存在一些特别的假设。也许你的代码混入了空指针,而原始代码从未检查过。如果你能解决这些问题,那么就可以理解为你的老板得到了两位程序员共同努力的成果。这就是某种形式的结对编程,而且用不着什么高大上的办公桌。 不良的编程习惯TOP2:非函数式代码 在过去十年间,函数范式愈加流行。喜欢用嵌套函数调用来构建程序的人们引用了很多研究成果。这些研究表明,与旧式的变量和循环相比,函数式编程代码更安全,错误更少,而且可以随程序员的喜好任意组合在一起。粉丝们十分追捧函数式编程,还会在代码审查和拉取请求中诋毁非函数式方法。关于这种方法的优势,他们的观点其实并没有错。 但有时你需要的仅仅是一卷胶带而已。精心设计并细心计划的代码需要花费很多时间,不仅需要花费时间想象,还需要构建和之后导航的时间。这些都增加了复杂性,并且会花费很多的时间与精力。开发漂亮的函数式代码需要提前做计划,还要确保所有数据都通过正确的途径传递。有时找出并更改变量会简单得多,可能再加个注释说明一下就够了。就算要在注释中为之后的程序员致以冗长而难懂的歉意,也比重新设计整个系统,把它扳回正轨上要省事得多。 不良的编程习惯第 3 位:非标准间距 软件中的大多数空格都不会影响程序的性能。除少数使用间距指示代码块的语言(如 Python)外,大多数空格对程序行为的影响为零。尽管如此,仍然有一些得了强迫症的程序员会数空格,并坚持认为它们很重要。曾有这样一位程序员以最严肃的口吻告诉我的老板,说我正在写“非标准代码”,还说他一眼就看出来了。我的错咯?因为我没在等号的两侧放置空格,违反了 ESLint space-infix-ops 规则[1]。 有时候你只要操心那些更深层的内容就行了,谁管什么空格的位置。也许你担心数据库过载,也许你担心空指针可能会让你的代码崩溃。一套代码中,几乎所有的部分都比空格更重要,就算那些喜欢走形式的标准委员会写出来一大堆规则来限制这些空格或制表符的位置,那又如何呢。 令人欣喜的是,网上可以找到一些很好用的工具来自动重新格式化你的代码,让你的代码遵守所有精心定义的 linting 规则。人类不应该在这种事情上浪费时间和脑细胞。如果这些规则这么重要,我们就应该用工具来解决这些问题。 不良的编程习惯第 4 位:使用 goto 禁止使用 goto 的规则可以追溯到许多结构化编程工具还没有出现的时代。如果程序员想创建一个循环或跳转到另一个例程,则需要键入 goto,后跟一个行号。多年之后,编译器团队开始允许程序员使用字符串标签来代替行号。这在当时被认为是一项热门的新特性。 有的人把这样做法的结果称为“意大利面条式代码”。因为以后没人能读懂你的代码,没人搞得清楚执行路径。成为一团混乱的线程,缠结在一起。Edsger Dijkstra 写过一篇题为“我们认为 goto 声明是有害的”的一篇文章[2],号召大家拒绝使用这个命令。 但是绝对分支并不是问题所在,问题在于它产生的那堆纠缠的结果。一般来说,精心设计的 break 或 return 能提供有关该位置的代码执行情况的非常清晰的陈述。有时,将 goto 添加到一个 case 语句中所生成的东西与联 if-then-else 块的相比,结构更正确的列表理解起来更容易。 也有反例。苹果 SSL 堆栈中的“goto fail”安全漏洞[3]就是一个很好的例子。但是,如果我们谨慎地避免 case 语句和循环中出现的一些问题,我们就可以插入很好用的绝对跳转,使代码读者更容易理解正在发生的事情。有时我们可以放一个 break 或 return,不仅更简洁,而且大家读起来更愉快,除了那些讨厌 goto 的人们。 不良的编程习惯第 5 位:不声明类型 热爱类型化语言的人们有他们的理由。当我们为每个变量的数据类型添加清晰的声明时,我们会编写更好,错误更少的代码。花点时间来阐明类型,就可以帮助编译器在代码开始运行之前标记出愚蠢的错误。这可能会很痛苦,但也会有回报。这是一种编程的笨办法,就是为了避免错误。 时代变了。许多较新的编译器已经足够聪明了,它们可以在查看代码时推断出类型。它们可以在代码中前后移动,最后确认变量应该是 string 或 int,抑或是其他类型。而且,如果推断出来的这些类型没法对齐,则编译器会给出错误标志。它们不需要我们再类型化变量了。 换句话说,我们可以省略一些最简单的声明,然后就能轻松节省一些时间了。代码变得更简洁,代码读者也往往能猜出 for 循环中名为 i 的变量是一个整数。 不良的编程习惯第 6 位:溜溜球代码 程序员喜欢将其称为“yo-yo 代码”。首先,这些值将存储为字符串,然后将它们解析为整数,接下来将它们转换回字符串。这种方法效率极低。你几乎能感受到一大堆额外负载让 CPU 不堪重负的样子。能快速编写代码的聪明程序员会调整自己的代码架构,以最大程度地减少转换。因为他们安排好了计划,他们的代码也能跑得更快。 但不管你信不信,有时溜溜球代码也是有意义的。有的时候,你需要用一个可以在自己的黑匣子里搞定一大堆智能操作的库。有的老板花了很多钱,请好多天才做出来这么一个库。如果这个库需要字符串形式的数据,那么你就得给它字符串,就算你最近刚把数据转换为整数也得再转回去。 当然,你可以重写所有代码以最大程度地减少转换,但这会花费一些时间。有时,代码多运行一分钟、一小时、一天甚至一周也是可以接受的,因为重写代码会花费更多时间。有时候,增加技术债务要比重新建立一笔技术债的成本更低些。 有时这种库里面不是专有代码,而是你很久以前编写的代码。有时,转换一次数据要比重写该库中的所有内容更省事。这种时候你就可以编写悠悠球代码了,不要怕,我们都遇到过这种事情。 不良的编程习惯第7位:编写自己的数据结构 有一条标准规则是,程序员在大二学完数据结构课程后,再也不要编写用于存储数据的代码了。已经有人编写过了我们所需要的所有数据结构,并且他们的代码经过了多年的测试和重新测试。这些结构与语言打包在一起,还可能是免费的。你自己写的代码只会是一堆错误。 但有的时候数据结构库的速度有点缓慢。有时候我们被迫使用的标准结构并不适合我们自己的代码。有时,库会要求我们在使用它的结构之前重新配置数据。有时,这些库带有笨重的保护,还有一些诸如线程锁定之类的特性,而我们的代码并不需要它们。 发生这种情况时就该编写我们自己的数据结构了。有时我们自己的结构会快很多,还可能让我们的代码更整洁,因为我们不需要一大堆额外的代码来重新精确地格式化数据。 不良的编程习惯第 8 位:老式循环 很久以前,创建 C 语言的某人想将所有抽象可能性封装在一个简单的构造中。这个构造开始时要做一些事情,每次循环都要做一些事情,所有事情都完成时还有一些方法来提示我们。当时,这似乎是一种拥有无限可能性的完美语法。 此一时彼一时,如今一些现代评论者只看到了其中的麻烦,发生的事情太多了,所有这些可能性既可能向善也可能作恶。这种构造让阅读和理解代码变得非常困难。他们喜欢更加函数式的的范式,其中没有循环,只有应用到列表的函数,还有映射到某些数据的计算模板。 有时无循环方法更简洁,尤其是当我们只有一个简单的函数和一个数组的时候。但还有些时候,老式的循环要简单得多,因为它可以做更多事情。例如,当你找到第一个匹配项后就立刻停止搜索,这样的代码就简单得多。 此外,要对数据执行多项操作时,映射函数会要求更严格的编码。假设你要对每个数字取绝对值,然后取平方根,最快的方案是先映射第一个函数,然后映射第二个函数,将数据循环两次。 不良的编程习惯第 9 位:在中间打破循环 从有一天开始,一个规则制定小组宣布每个循环都应该有一个“不变项”,就是一个在整个循环中都为真的逻辑语句。当不变量不再为真时,循环就结束了。这是处理复杂循环的好方法,但会带来一些令人抓狂的约束,例如禁止我们在循环中间使用 return 或 break。这条规则是禁止 goto 语句规则的子集。 这个理论很不错,但它通常会导致代码变得更复杂。考虑以下这种简单的情况,其中会扫描一个数组,找出通过测试的一个条目: while (i<a.length){ ... if (test(a[i]) then return a[i]; ... } 喜欢循环不变项的人们宁愿我们添加另一个布尔变量,将其称为 notFound,然后这样用它: while ((notFound) && (i<a.length){ ... if (test(a[i])) then notFound=false; ... } 如果这个布尔名称取得很合适,那就会是一段自我注释得很好的代码。它可以让大家理解起来更容易。但这也增加了复杂性。这还意味着要分配另一个局部变量并阻塞一个寄存器,编译器可能没那么聪明,没法修复这个错误。 有时使用 goto 或 jump 会更简洁。 不良的编程习惯第10位:重载运算符和函数 一些有趣的语言会让你绕一些大弯子,比如说重新定义看起来应该是常量的元素值。拿 Python 来说,至少在 2.7 版及更低版本中,它允许你键入 TRUE=FALSE。这不会引发某种逻辑崩溃,也不会导致宇宙的终结;它只是交换了 TRUE 和 FALSE 的含义。你还可以使用 C 预处理器和其他一些语言来玩这种危险的游戏。还有一些语言允许你重新定义加号之类的运算符。 有时候,在一大段代码中重新定义一个或一些所谓常量,结果效率会更高。有时,老板会希望代码执行完全不同的操作。当然,你可以检查代码,逐一更改对应的部分,也可以干脆重新定义现实来节省时间。别人会觉得你是天才。用不着重写庞大的库,只需翻转一下即可。 这里也许应该划一条底线。无论这种做法多有意思,看起来多聪明,你都不应该在家里做实验。这太危险了——我是认真的。
茶什i 2019-12-30 11:01:01 0 浏览量 回答数 0
阿里云企业服务平台 陈四清的老板信息查询 上海奇点人才服务相关的云产品 爱迪商标注册信息 安徽华轩堂药业的公司信息查询 小程序定制 上海微企信息技术相关的云产品 国内短信套餐包 ECS云服务器安全配置相关的云产品 天籁阁商标注册信息 开发者问答 阿里云建站 自然场景识别相关的云产品 万网 小程序开发制作 视频内容分析 视频集锦 代理记账服务 北京芙蓉天下的公司信息查询