作者归档:文广

连载:全球最牛的28个大数据可视化应用案例(一)

声明:本文由入驻搜狐公众平台的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。举报

  随着大数据在人们工作及日常生活中的应用,大数据可视化也改变着人类的对信息的阅读和理解方式。从百度迁徙到谷歌流感趋势,再到阿里云推出县域经济可视化产品,大数据技术和大数据可视化都是幕后的英雄。今天,我们将连载由Teradata独家提供的来自全球28个大数据可视化应用案例。文章中不仅有极具艺术美感的可视化炫图,更有作者为大家解析可视化是如何制作的。

本系列4篇文章为36大数据独家专稿,任何不表明来源36大数据和Teradata以及本文链接http://www.36dsj.com/archives/41214的转载均为侵权。公众号也是如此。

一、航线星云

作者:Karthik Guruswamy

关于洞察

截止到2012年1月,开源网站OPENFLIGHTS.ORG上记载了大约6万条直飞航班信息,这些航班穿梭在3000多个机场间,覆盖了500多条航线。

通过高级分析技术,我们可以看到世界上各家不同的航空公司看起来就像是一个美丽的星云(国际星云的组成部分)。同种颜色的圆点和粗线提供了见解,它们代表提供相同航线的航空公司,显示出它们之间的竞争以及在不同区域间的潜在合作。

这张基于数据可视化的Sigma图表显示了服务城市相似的不同航空公司。图中的圆点或圆圈代表航空公司,连线的粗细和远近则反映两个航空公司之间的相似性;连线越粗或越短则代表两家航司服务的城市越相似。图表中有几组航空公司,直观地表现了它们所服务的地理区域。

这张图表中的关键洞察当然地是航空公司之间的相似性甚至是重叠,它们是中国的南航和东航、阿联酋航空和卡塔尔航空、英航和汉莎航空、美航和达美航空;我们可以从中看出这些公司之间的竞争关系。瑞安航空则通过服务与汉莎航空和英航存在潜在协力的城市占据了一个利基市场;比起意大利或汉莎等其他的欧洲航司,法国航空则与美国联航等美国航空公司更为相似,这也许可以解释为联合品牌效应。本质上说,这是一张多维的韦恩图,用一种简明扼要的方式揭示了不同主体间的复杂关系。

总的来说,这张图表揭示了不同航司之间的相似性和竞争情况,有利于发掘潜在的合作关系、增加市场份额和市场覆盖面。这项技术可以通过不同参与者之间的相同变量,用于分析任何生态系统。

分析技术

这张可视化图表通过Aster App中心生成,运用到了关联挖掘的分析技术,研究上下文中各条目的共现关系。其中关联挖掘的算法是协同过滤,它作用于航线和城市数据,并将数据当做零售篮子数据。也就是说,篮子代表城市,而航空公司则是条目。两个航司之间的相似性由相似性得分确定,计分的原则是比较各个航司独有的航线以及同时运营的航线。之后再将这些成对的相似性得分当做连线的权重,再把各个航司当做节点,共同输入可视化仪器当中,运用具有模块上色技术的force-atlas算法,最终生成出这张美丽的图表。

二、Calling Circles

作者:Christopher Hillman

关于洞察

我们无论何时何地都在使用手机并且产生出非常大量的资料,这些资料代表了我们每天的行为及活动。我们与其他人的每通电话及简讯都对应到我们的社会关系、商业活动以及更广泛的社群互动并且形成了许多复杂互相联结的通话圈。

这个资料视觉化图表是从行动电话使用者的通话模式资料所制作的。每个点都代表一个使用者拨出的手机号码,愈大的点就代表这个号码被拨打愈多次。每条两点之间的线都代表着从一个号码拨打到另一个号码。

每个行动电话使用者都会有一种独特的通话模式,这种模式可以用来发展适合的话费方案并且可以用来定义或预测他/她的行为。举例来说,当一个使用者正要从现在的行动电话服务商转换到另一个服务商时,我们可以从网内及网外发现两个类似的通话模式。

这张特别的图表是在前期由一连串的分析产生用来过滤第一层的通话模式。这里使用到的资料只从在几秒钟的时间取得。从图表的左上角可以看到许多大回圈,这些回圈表示短时间内这些号码被拨打了许多次。可以推测这些号码有可能是机器,像是自动答录机、互动式语音应答(IVR) 系统、安全系统或警报。人类不可能在短时间拨出这么多电话。这些电话会先放置在一个分开的群组,后续的分析就可以集中在个人使用者的通话模式上。

分析技术

我们利用图表来达成资料视觉化,虽然在调整版面格式的参数与传统展示图表不同。有一个常见的问题就是这些互连的图表通常在短时间就会变成非常巨大且因为庞大的互动次数导致几乎不可能被视觉化。从一个高度连结的图表里选出一段范例是一个困难的问题,因为我们需要决定忽略哪些连结。在这个例子里,我们取用来自非常短的时间的资料来达到一个可以呈现的资料范围。

资料格式就相对简单,拨话号码、收话号码、拨话时间、通话时间。我们先利用机器学习(machine-learning) 来对资料作分群然后再利用Aster Lens 来展示图表。

Calling Circles作者介绍

Christopher Hillman

Christopher Hillman 跟他的妻子及两个小孩住在英国伦敦,在Teradata 的进阶分析团队(Advanced Analytics team) 担任首席资料科学家在全世界旅行工作。

他钟情于分析工作且有二十年的经验于商业智慧(business intelligence) 及进阶的分析产业。在Teradata 之前,Chris在Retail 和CPGN vertical作为一位解决方案架构师(solution architect)、首席顾问及技术总监。 Chris 现在与Teradata Aster 专家一同工作且参与大数据的分析专案,他帮助客户洞察资料中的价值并且了解MapReduce 或SQL 作为合适的技术。

在Teradata 工作的期间,Christopher 也同时攻读在Dundee 大学的资料科学博士并运用大数据分析在人类蛋白类的实验资料上。他的研究领域包含利用平行化演算法即时分析质谱仪的资料。他也在大学开课教授Hadoop 及MapReduce 程式设计。

三、信号风暴骑士

作者:桑德拉.拉曼 (Sundara Raman)

关于洞察

此可视化捕捉了桑德拉.拉曼在澳大利亚悉尼通勤列车廊道的旅程。桑德拉携带其手机和专用软件乘坐列车穿行于悉尼, 由于列车快速穿过城市, 我们可以通过其手机与信号发射塔的连接来跟踪, 用彩点(或节点)描绘在图表上。

利用手机数据对运动中的、聚集大量人群的交通模式进行研究是新分析形式的一部分。其主要目的在于优化发射塔网络、避免性能问题、改善客户体验。但它还能支持新兴数据货币化发展,详细的交通流量信息可用于城市规划、零售商店位置分析和市场营销供应。

桑德拉在分析中探寻能击垮发射塔、影响手机性能的信号“风暴”。当拥挤的通勤列车奔跑于轨道线上,后停于车站,列车发出的100-1000个信号快速移动于各发射塔之间,就足以击垮它们。该可视化是一系列图表的一部分,覆盖了发射塔性能数据、通勤交通流量以及塔切换的信息,准确表现出手机信号的“风暴潮”,从而据此提出详细的建议来优化网络。

图表中还能突显出特定客户体验时由于在4G发射塔(暗点)和低速3G发射塔(亮点)间切换而出现的问题—-信号在发射塔之间来回反复切换,塔信号强度剧烈变化,产生“乒乓效应”。典型代表是位于林菲尔德、可莱雅、怀塔拉、北悉尼以及查茨伍德各车站附近的相连的封闭式发射塔群。

分析方法

该可视化是通过Teradata Aster和Aster Lens实现的。智能手机的遥信数据是从同时使用的3G和4G手机中收集的, 收集在拥挤的公共交通路线上使用专用软件的数据, 地点是沿着澳大利亚悉尼北岸线和史卓菲市交通线一带。分析还包括了对火车站和信号发射塔位置数据的地理空间分析, 从而将位于火车站方圆1公里内的发射塔隔离出来。这个方法有助于衡量确定小范围内,车站周围各发射塔之间信号传播的影响。另外GEXF西格玛图表中还添加了颜色代码, 利用可视化语言统一地区分4G和3G信号发射塔的区域。每种颜色代表一组发射塔的网络覆盖区域。悉尼城市铁路公布的统计数据涉及峰值时间每个车站火车的交通负荷, 分析则利用这一数据关联了手机站点的性能。

作者介绍

桑德拉.拉曼 (Sundara Raman)

桑德拉白天是一位高级电信行业咨询师, 夜间则是一位胸怀大志的数据科学家。他在新西兰梅西大学获得商业管理硕士学位, 现在与妻子及2个孩子住在澳大利亚的悉尼。

桑德拉还是一名发明家, 他曾与他的妻子共同应用“认知行为疗法”(CBT)原则, 设计出“计算机辅助心理评估与治疗”, 获得了澳大利亚一项专利权。

所以, 如果你在下一个日常通勤时碰巧瞥见桑德拉在把玩多个手机, 你就会明白他不是疯了。他只是在利用分析获得深入见解, 从而帮助电信客户改善移动网络的客户体验。

四、互联网络

作者:Yasmeen Ahmad

关于洞察

这一匿名可视化报告用于支持一家Telco运营商分析住宅Telco线路。该项目旨在确定线路与网络硬件性能之间的关联,此类关联可能影响到客户体验。

点(节点)代表Telco网络上的DSLAM(数字用户线接入复用器)。DSLAM提供了一项重要服务,能够影响客户呼叫体验;它们可将客户线路连接到主网络。

DSLAM服务级别有多项测量指标,例如衰减、比特率、噪声容限和输出功率,并可针对每条线路整合至三个性能类别。紫色节点显示具备卓越性能的DSLAM,橙色显示具备出色性能的DSLAM,白色显示性能较差的DSLAM。

在图表中,仅少数DSLAM体验到了高质量服务(紫色)。这些 DSLAM 在同一建筑中与主网络基础设施共置,由于靠近中央网络中枢,从而带来了优质服务。大多数客户实现了出色体验(橙色),同时我们发现城市郊区存在服务较差(白色)的DSLAM。

当客户获得可变网络质量时,客户体验和满意度会受到很大影响。Telco的主要目标是确保客户获得一致的体验,即使是那些身处主城市外部的用户也不例外。此图表确定了每个提供可变服务级别的 DSALM;以出色(橙色)和较差(白色)簇之间共享的节点表示。借助这一数据,Telco现在能够调查和优化可变DSLAM。

分析方法

这一西格玛可视化报告使用内建分析和在Teradata Aster平台内发现的可视化创建而成。

收到的数据来自整个城市的住宅线路,其属性包括衰减、比特率等。我们对这些属性进行了整合,以确定表明客户网络体验的性能等级。

这些簇构成了相关性和回归分析的基础,以确定在不同因素下网络性能的变化,这些因素包括:线路技术和长度、调制解调器类型和配置、DSLAM、卡技术、地理位置等。

该西格马可视化图表仅显示了整体分析的一部分,即DSLAM与网络性能间的联系。

作者介绍

Yasmeen Ahmad

Yasmeen是Teradata的最有创意和有见地的数据科学家之一。 Yasmeen在苏格兰长大,她喜欢户外活动,尤其是在苏格兰Munros山和在海上划皮艇。

她在许多国家工作过,包括英国、爱尔兰、荷兰土耳其、比利时和丹麦,她涵盖了金融,电信,零售和公用事业等行业。 Yasmeen专精与企业合作以确定他们的挑战,并将其转化为分析背景。她专注于企业如何利用新的或尚未开发的数据来源,沿着新技术以提高自身的竞争能力的独特能力。

Yasmeen已经与许多分析团队工作,提供领导,培训,指导和实践的支持,提供可操作的见解和经营成果。她使用各种分析方法,包括文本分析,预测建模,归属策略和时间序列分析的发展。她坚信可视化的力量使的在企业用户可以容易进行复杂的沟通。

在Teradata之前,Yasmeen在生命科学行业工作作为数据科学家,建设复杂、多维数据分析管线。 Yasmeen还持有数据管理,挖掘和可视化,这是进行在威康信托中心的基因调控和表达的博士学位。她在国际上发表了多篇论文并在国际会议和活动中演讲。此外,她还在MSc教有关科学数据和商业智能硕士课程。

Yasmeen对于数据分析和可视化有敏锐的热情,通过她的研究中一直好奇地问问题并了解更多信息。这些技能已经允许Yasmeen探索多学科的机会,为她提供了新的无尽的挑战!

五、连续性集装箱修理

作者:Frances Luk

关于洞察

物流集装箱在运输过程中常常会受到损伤,而这些集装箱的修理则依靠世界各地数以百计的供应商来处理。在通常情况下,如果状况不好无法继续使用,受损的集装箱会在被运往下个目的地之前就近修理。我们的客户是全世界最大的一家物流公司,他们希望了解集装箱的修理质量以及各个提供修理的供应商。在进行这项分析之前,客户无法获知集装箱使用寿命当中所发生事件的整体概览。而通过重现每个集装箱使用寿命当中发生的所有事件,我们成功地分析出了集装箱的修理模式。

通过这项分析,客户希望找出因为同一种损伤原因而发生的连续的修理活动,规定这两次修理发生在某一段时间内,或者说第二次修理比预期的时间提前了。这种活动表示早期修理的质量较差,从而造成了第二次的修理。这张桑基图中第一列的方框代表负责第一次修理的国家。

第二列的方框则代表负责第二次修理的国家。从第一列方框直接连到‘结束’框的则代表在第一次修理之后没有再发生修理行为,这是理想的状况;连到第二栏方框的则是意外情况。这张可视化图表让我们的客户得以按地域查看提供修理的供应商,未来还可能在工厂层级继续深钻。

分析技术

集装箱修理活动通过内建的数据装载器从Teradata数据库牵引到了Aster数据库中。我们利用事件序列和模式匹配技术来鉴别连续性修理活动。我们利用这张桑基图来比较不同国家修理工厂的质量,图中的线越粗则表示两个国家共同出现的次数越多。这张图表提供了极佳的整合信息,显示出应该关注于哪个国家,接下去可以利用数据来计算重点关注国家发生第二次修理的相对频率。这张桑基图通过Aster平台中的Aster Lens生成。

作者介绍

Frances Luk

Frances Luk是丹麦哥本哈根团队的一名数据科学家。她从小在香港长大,但某天却决定要去做一些不一样的事情,现在和她的丈夫还有两只可爱的小猫一起在丹麦生活,还拥有哥本哈根大学的硕士学位。在成为数据科学家之前,她曾经用五年时间来开发企业Java应用,并有七年从事银行和物流行业的数据仓库和数据分析的经验,现在负责丹麦和其他北欧国家的跨行业售前和大数据管理PS服务。

Frances对数据科学的热情来源于她强大的技术背景以及她对商业强烈的好奇心。每一比特的数据对她来说都像是一个谜,她喜欢拼凑细节并享受美丽图像产生的那一刻,喜欢看到客户发现未知的洞察时脸上惊叹的表情,这就是她每天工作的功力。

六、集装箱修理波浪

作者:Frances Luk

关于洞察

在通过遍布世界的船舶、卡车、火车进行运输的时候,集装箱时时会受到损伤。损伤情况发生时,集装箱会被运到最近的修理铺里,而这些成百上千个的修理铺散布在世界的各个角落。

我们的客户马士基航运公司希望加强他们对不同修理铺修理质量的了解。过去他们无法在每一个集装箱的层级上对这些数据进行分析,但Teradata Aster平台让马士基航运能够在这个层级调查并分析修理结果,获取有趣的发现、了解它们的模式和趋势,而这是前所未有的。

这张可视化图表中右下方的点代表不同的修理活动,曲线上方的点则表示不同的商品,商品和修理活动之间的连线则代表运输某种商品之后马上发生某种修理活动的频率;连线越粗表示运过某种商品后集装箱发生修理的频率越高。从图中可以看到,最粗的线连接着废金属和底板损伤,也就是说最经常出现的商品和修理类型配对是废金属和集装箱底板修理。

对于马士基航运来说,知道废金属最经常导致破损当然不是什么新鲜事,但采集到的这些数据为将来的分析奠定了强大的基础,(自然可以延伸到考虑比如比起其他货品,是不是更经常要运送废金属)。我们不能完全肯定废金属和底板破损之间的因果关系,但这张可视化图表却突出了问题的规模,建立了马士基航运公司的高级分析团队未来进行更细致的分析时的好的起点。将来的分析工作完成时,最终得到的结果可能就是更差异化的货运定价模型,抵减预计的运后修理成本。

分析技术

集装箱运输和修理活动通过内建的数据加载器从Teradata牵引到Aster当中。通过和马士基航运的ADL(敏捷数据实验室)和AA(高级分析)团队紧密合作,我们确定了适合的途径,用来分析货物和修理之间的关系,并应用模式匹配技术调查连续性运输和修理的模式。

之后我们用sigma可视化工具来展现货物和修理类型之间的关系,这两者在图中表示为实心点,连线的粗细表示共现的次数。初始sigma图通过Aster平台中的Aster Lens生成,现在展现的是优化版本。

作者介绍

Frances Luk,同连续性集装箱修理是一个作者。

七、Terror Report

作者:Kailash Purang

关于洞察

这份资料视觉化是Kailash Purang两部分CIA 报告的第一部分。它展示了进阶分析可以快速地客观地从复杂的文件精炼成简单易懂的视觉化图表。这份图表应该与第两部分的报告(Crown Of Thorns) 一起被检视。

Kailash 刻意挑选了一个具高度政治及情绪相关的主题,这份报告是美国参议院特别委员会研究院针对2001 到2006 年CIA(Central Intelligence Agency) 拘留和审讯程序及审讯拷打的研究。

这是一份相当长的报告,总共从6000 页中有525 页被公开,其中包含特定的政府用词以及在技术文件上会有的专有名词。这是份极端重要的文件以至于少数人可以第一手阅读到并且提供自己的意见,大部分人只能从其他人写的摘要报告接触到。然而像这样泛政治化及情绪性的主题,我们如何确定我们读到的摘要是完全正确且没有其他人的主观意见呢?

简短地来说,这是一个对于测试分析工作是否可以提供一个简单客观的方法来检视报告内容的理想主题。

Kaliash 的第一个视觉化图表”恐怖攻击” 是简单的文字云(word cloud),报告里愈常出现的特定文字在图表上呈现愈大的图形。文字云这样的图表可以很快速被制作,也可以轻易客观被吸收。然而,太粗浅的呈现是它的限制,我们从中可看到关键字,但是并无法从图表中得知任何的细节也无法知道各个主题中间的关联。文字云提供我们一个快速且非常简单的方式来了解报告里的内容。

请接着阅读第二部分“Crown Of Thorrns” 。

分析方法

这份视觉化使用525 页的中央情报局委员拘留及审讯计划报告,这份报告是于2014 年12月9号由美国参议院情报委员会公开发表。

这份图表是使用Wordle 制作的,Wordle 是一个由Jonathon Feinberg发表的文字云制作程式且可以从网站上免费取得。我们可以利用英文里的剔除字(stop word) 来移除低资讯价值的字像”的”跟”了”。制作的图表留下最常出现的字词,读者可以简单地从字词出现的频率得到结论。

作者介绍

Kailash Purang

Kailash 是在Teradata新加坡资料科学家领导人。他也在整个东南亚工作,大部分在印尼支援及领导Teradata在银行及通讯产业客户的服务。

Kailash 有新加坡国立大学经济硕士经济跟统计学学士、新加坡国立大学经济硕士、伦敦大学管理学学士。他在分析领域有长达15年跟产业的经验。

尽管是”出卖灵魂” 投身商业领域,他仍然认为所有这一切的学习和技术的目的是为了让人们的生活更轻松更有趣。为了引进一个有趣的无痛的分析方式,他在业余时间作资料视觉化让每个人都可以从简单的分析应用过程中获益。

作为Teradata资料科学家,他努力使自己的客户实现大数据的全部潜力,使他们的客户可以通过更好的服务和产品受益。

——————

未完待续,明天我们将连载全球最牛的28个大数据可视化应用案例(二)

End.

android uses-permission

<!– 访问网络 –>
<uses-permission android:name=”android.permission.INTERNET”/>
<!– 写外部存储 –>
<uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE”/>
<!– 进行网络定位 –>
<uses-permission android:name=”android.permission.ACCESS_COARSE_LOCATION”/>
<!– 访问GPS定位–>
<uses-permission android:name=”android.permission.ACCESS_FINE_LOCATION”/> <uses-permission android:name=”android.permission.ACCESS_MOCK_LOCATION”/>
<!– 获取运营商信息,用于支持提供运营商信息相关的接口–>
<uses-permission android:name=”android.permission.ACCESS_NETWORK_STATE”/>
<!– 访问wifi网络信息,wifi信息可用于进行网络定位–>
<uses-permission android:name=”android.permission.ACCESS_WIFI_STATE”/>
<!– 获取wifi的获取权限,wifi信息可用来进行网络定位–>
<uses-permission android:name=”android.permission.CHANGE_WIFI_STATE”/>
<!– 唤醒CPU –>
<uses-permission android:name=”android.permission.WAKE_LOCK”/>
<!– 控制振动器–>
<uses-permission android:name=”android.permission.VIBRATE”/>
<!– 使用摄像头–>
<uses-permission android:name=”android.permission.CAMERA”/>
<!– 直接拨打电话–>
<uses-permission android:name=”android.permission.CALL_PHONE”/>
<!– 直接发送短信–>
<uses-permission android:name=”android.permission.SEND_SMS”/>
<!– 读取手机当前的状态–>
<uses-permission android:name=”android.permission.READ_PHONE_STATE”/>
<!– 读取手机通讯录–>
<uses-permission android:name=”android.permission.READ_CONTACTS”/>
<!– 写入手机通讯录–>
<uses-permission android:name=”android.permission.WRITE_CONTACTS”/>
<!– 录音–>
<uses-permission android:name=”android.permission.RECORD_AUDIO”/>
<!– 闪光灯–>
<uses-permission android:name=”android.permission.FLASHLIGHT”/>
<!– 读取低级别的系统日志文件–>
<uses-permission android:name=”android.permission.READ_LOGS”/>
<!– 开机启动–>
<uses-permission android:name=”android.permission.RECEIVE_BOOT_COMPLETED”/>
<!– 蓝牙账户–>
<uses-permission android:name=”android.permission.BLUETOOTH_ADMIN”/>
<!– 蓝牙–>
<uses-permission android:name=”android.permission.BLUETOOTH”/>
<!– 手机必要要有照相机 且能自动对焦–>
<uses-feature android:name=”android.hardware.camera”/> <uses-feature android:name=”android.hardware.camera.autofocus” android:required=”false”/> <uses-permission android:name=”android.permission.DOWNLOAD_WITHOUT_NOTIFICATION”/>

优秀程序员眼中的整洁代码

有多少程序员,就有多少定义。所以我只询问了一些非常知名且经验丰富的程序员。
Bjarne Stroustrup,C++语言发明者,C++ Programming Language(中译版《C++程序设计语言》)一书作者。

我喜欢优雅和高效的代码。代码逻辑应当直截了当,叫缺陷难以隐藏;尽量减少依赖关系,使之便于维护;依据某种分层战略完善错误处理代码;性能调至最优,省得引诱别人做没规矩的优化,搞出一堆混乱来。整洁的代码只做好一件事。

Bjarne 用了“优雅”一词。说得好!我 MacBook 上的词典提供了如下定义:外表或举止上令人愉悦的优美和雅观;令人愉悦的精致和简单。注意对“愉悦”一词的强调。Bjarne 显然认为整洁的代码读起来令人愉悦。读这种代码,就像见到手工精美的音乐盒或者设计精良的汽车一般,让你会心一笑。

Bjarne 也提到效率——而且两次提及。这话出自 C++ 发明者之口,或许并不出奇;不过我认为并非是在单纯追求速度。被浪费掉的运算周期并不雅观,并不令人愉悦。留意 Bjarne 怎么描述那种不雅观的结果。他用了“引诱”这个词。诚哉斯言。糟糕的代码引发混乱!别人修改糟糕的代码时,往往会越改越烂。

务实的 Dave Thomas 和 Andy Hunt 从另一角度阐述了这种情况。他们提到破窗理论4。窗户破损了的建筑让人觉得似乎无人照管。于是别人也再不关心。他们放任窗户继续破损。最终自己也参加破坏活动,在外墙上涂鸦,任垃圾堆积。一扇破损的窗户开辟了大厦走向倾颓的道路。

Bjarne 也提到完善错误处理代码。往深处说就是在细节上花心思。敷衍了事的错误处理代码只是程序员忽视细节的一种表现。此外还有内存泄漏,还有竞态条件代码。还有前后不一致的命名方式。结果就是凸现出整洁代码对细节的重视。

Bjarne 以“整洁的代码只做好一件事”结束论断。毋庸置疑,软件设计的许多原则最终都会归结为这句警语。有那么多人发表过类似的言论。糟糕的代码想做太多事,它意图混乱、目的含混。整洁的代码力求集中。每个函数、每个类和每个模块都全神贯注于一事,完全不受四周细节的干扰和污染。

Grady Booch,Object Oriented Analysis and Design with Applications(中译版《面向对象分析与设计》)一书作者。

整洁的代码简单直接。整洁的代码如同优美的散文。整洁的代码从不隐藏设计者的意图,充满了干净利落的抽象和直截了当的控制语句。

Grady 的观点与 Bjarne 的观点有类似之处,但他从可读性的角度来定义。我特别喜欢“整洁的代码如同优美的散文”这种看法。想想你读过的某本好书。回忆一下,那些文字是如何在脑中形成影像!就像是看了场电影,对吧?还不止!你还看到那些人物,听到那些声音,体验到那些喜怒哀乐。

阅读整洁的代码和阅读 Lord of the Rings(中译版《指环王》)自然不同。不过,仍有可类比之处。如同一本好的小说般,整洁的代码应当明确地展现出要解决问题的张力。它应当将这种张力推至高潮,以某种显而易见的方案解决问题和张力,使读者发出“啊哈!本当如此!”的感叹。

窃以为 Grady 所谓“干净利落的抽象”(crisp abstraction),乃是绝妙的矛盾修辞法。毕竟 crisp 几乎就是“具体”(concrete)的同义词。我 MacBook 上的词典这样定义 crisp 一词:果断决绝,就事论事,没有犹豫或不必要的细节。尽管有两种不同的定义,该词还是承载了有力的信息。代码应当讲述事实,不引人猜测。它只该包含必需之物。读者应当感受到我们的果断决绝。

“老大”Dave Thomas,OTI 公司创始人,Eclipse 战略教父。

整洁的代码应可由作者之外的开发者阅读和增补。它应当有单元测试和验收测试。它使用有意义的命名。它只提供一种而非多种做一件事的途径。它只有尽量少的依赖关系,而且要明确地定义和提供清晰、尽量少的 API。代码应通过其字面表达含义,因为不同的语言导致并非所有必需信息均可通过代码自身清晰表达。

Dave 老大在可读性上和 Grady 持相同观点,但有一个重要的不同之处。Dave 断言,整洁的代码便于其他人加以增补。这看似显而易见,但亦不可过分强调。毕竟易读的代码和易修改的代码之间还是有区别的。

Dave 将整洁系于测试之上!要在十年之前,这会让人大跌眼镜。但测试驱动开发(Test Driven Development)已在行业中造成了深远影响,成为基础规程之一。Dave 说得对。没有测试的代码不干净。不管它有多优雅,不管有多可读、多易理解,微乎测试,其不洁亦可知也。

Dave 两次提及“尽量少”。显然,他推崇小块的代码。实际上,从有软件起人们就在反复强调这一点。越小越好。

Dave 也提到,代码应在字面上表达其含义。这一观点源自 Knuth 的“字面编程”(literate programming)5。结论就是应当用人类可读的方式来写代码。

Michael Feathers,Working Effectively with Legacy Code(中译版《修改代码的艺术》)一书作者。

我可以列出我留意到的整洁代码的所有特点,但其中有一条是根本性的。整洁的代码总是看起来像是某位特别在意它的人写的。几乎没有改进的余地。代码作者什么都想到了,如果你企图改进它,总会回到原点,赞叹某人留给你的代码——全心投入的某人留下的代码。

一言以蔽之:在意。这就是本书的题旨所在。或许该加个副标题,如何在意代码

Michael 一针见血。整洁代码就是作者着力照料的代码。有人曾花时间让它保持简单有序。他们适当地关注到了细节。他们在意过。

Ron Jeffries,Extreme Programming Installed(中译版《极限编程实施》)以及 Extreme Programming Adventures in C#(中译版《C#极限编程探险》)作者。

Ron 初入行就在战略空军司令部(Strategic Air Command)编写 Fortran 程序,此后几乎在每种机器上编写过每种语言的代码。他的言论值得咀嚼。

近年来,我开始研究贝克的简单代码规则,差不多也都琢磨透了。简单代码,依其重要顺序:

能通过所有测试;

没有重复代码;

体现系统中的全部设计理念;

包括尽量少的实体,比如类、方法、函数等。

在以上诸项中,我最在意代码重复。如果同一段代码反复出现,就表示某种想法未在代码中得到良好的体现。我尽力去找出到底那是什么,然后再尽力更清晰地表达出来。

在我看来,有意义的命名是体现表达力的一种方式,我往往会修改好几次才会定下名字来。借助 Eclipse 这样的现代编码工具,重命名代价极低,所以我无所顾忌。然而,表达力还不只体现在命名上。我也会检查对象或方法是否想做的事太多。如果对象功能太多,最好是切分为两个或多个对象。如果方法功能太多,我总是使用抽取手段(Extract Method)重构之,从而得到一个能较为清晰地说明自身功能的方法,以及另外数个说明如何实现这些功能的方法。

消除重复和提高表达力让我在整洁代码方面获益良多,只要铭记这两点,改进脏代码时就会大有不同。不过,我时常关注的另一规则就不太好解释了。

这么多年下来,我发现所有程序都由极为相似的元素构成。例如“在集合中查找某物”。不管是雇员记录数据库还是名-值对哈希表,或者某类条目的数组,我们都会发现自己想要从集合中找到某一特定条目。一旦出现这种情况,我通常会把实现手段封装到更抽象的方法或类中。这样做好处多多。

可以先用某种简单的手段,比如哈希表来实现这一功能,由于对搜索功能的引用指向了我那个小小的抽象,就能随需应变,修改实现手段。这样就既能快速前进,又能为未来的修改预留余地。

另外,该集合抽象常常提醒我留意“真正”在发生的事,避免随意实现集合行为,因为我真正需要的不过是某种简单的查找手段。

减少重复代码,提高表达力,提早构建简单抽象。这就是我写整洁代码的方法。

Ron 以寥寥数段文字概括了本书的全部内容。不要重复代码,只做一件事,表达力,小规模抽象。该有的都有了。

Ward Cunningham,Wiki 发明者,eXtreme Programming(极限编程)的创始人之一,Smalltalk 语言和面向对象的思想领袖。所有在意代码者的教父。

如果每个例程都让你感到深合己意,那就是整洁代码。如果代码让编程语言看起来像是专为解决那个问题而存在,就可以称之为漂亮的代码。

这种说法很 Ward。它教你听了之后就点头,然后继续听下去。如此在理,如此浅显,绝不故作高深。你大概以为此言深合己意吧。再走近点看看。

“……深合己意”。你最近一次看到深合己意的模块是什么时候?模块多半都繁复难解吧?难道没有触犯规则吗?你不是也曾挣扎着想抓住些从整个系统中散落而出的线索,编织进你在读的那个模块吗?你最近一次读到某段代码、并且如同对 Ward 的说法点头一般对这段代码点头,是什么时候的事了?

Ward 期望你不会为整洁代码所震惊。你无需花太多力气。那代码就是深合你意。它明确、简单、有力。每个模块都为下一个模块做好准备。每个模块都告诉你下一个模块会是怎样的。整洁的程序好到你根本不会注意到它。设计者把它做得像一切其他设计般简单。

那 Ward 有关“美”的说法又如何呢?我们都曾面临语言不是为要解决的问题所设计的困境。但 Ward 的说法又把球踢回我们这边。他说,漂亮的代码让编程语言像是专为解决那个问题而存在!所以,让语言变得简单的责任就在我们身上了!当心,语言是冥顽不化的!是程序员让语言显得简单。

 

摘自:http://begeek.cn/post/7210.html?_biz=MjM5OTA1MDUyMA==&mid=407358558&idx=2&sn=b21877f23bf4063fa311185009c1f0b7&scene=0#wechat_redirect1468885896550

程序员必须知道的10大基础实用算法及其讲解

算法一:快速排序算法

快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。

快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。

算法步骤:

1 从数列中挑出一个元素,称为 “基准”(pivot),

2 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。

3 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

Sorting_quicksort_anim

详细介绍:快速排序

算法二:堆排序算法

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

堆排序的平均时间复杂度为Ο(nlogn) 。

算法步骤:

  1. 创建一个堆H[0..n-1]
  2. 把堆首(最大值)和堆尾互换

3. 把堆的尺寸缩小1,并调用shift_down(0),目的是把新的数组顶端数据调整到相应位置

4. 重复步骤2,直到堆的尺寸为1

Sorting_heapsort_anim

详细介绍:堆排序

算法三:归并排序

归并排序(Merge sort,台湾译作:合并排序)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

算法步骤:

1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置

3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

4. 重复步骤3直到某一指针达到序列尾

5. 将另一序列剩下的所有元素直接复制到合并序列尾

Merge_sort_animation2

详细介绍:归并排序

算法四:二分查找算法

二分查找算法是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。折半搜索每次把搜索区域减少一半,时间复杂度为Ο(logn) 。

详细介绍:二分查找算法

算法五:BFPRT(线性查找算法)

BFPRT算法解决的问题十分经典,即从某n个元素的序列中选出第k大(第k小)的元素,通过巧妙的分析,BFPRT可以保证在最坏情况下仍为线性时间复杂度。该算法的思想与快速排序思想相似,当然,为使得算法在最坏情况下,依然能达到o(n)的时间复杂度,五位算法作者做了精妙的处理。

算法步骤:

1. 将n个元素每5个一组,分成n/5(上界)组。

2. 取出每一组的中位数,任意排序方法,比如插入排序。

3. 递归的调用selection算法查找上一步中所有中位数的中位数,设为x,偶数个中位数的情况下设定为选取中间小的一个。

4. 用x来分割数组,设小于等于x的个数为k,大于x的个数即为n-k。

5. 若i==k,返回x;若i<k,在小于x的元素中递归查找第i小的元素;若i>k,在大于x的元素中递归查找第i-k小的元素。

终止条件:n=1时,返回的即是i小元素。

详细介绍:

寻找最小(最大)的k个数

线性查找相关算法

算法六:DFS(深度优先搜索)

深度优先搜索算法(Depth-First-Search),是搜索算法的一种。它沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。DFS属于盲目搜索。

深度优先搜索是图论中的经典算法,利用深度优先搜索算法可以产生目标图的相应拓扑排序表,利用拓扑排序表可以方便的解决很多相关的图论问题,如最大路径问题等等。一般用堆数据结构来辅助实现DFS算法。

深度优先遍历图算法步骤:

1. 访问顶点v;

2. 依次从v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问;

3. 若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。

上述描述可能比较抽象,举个实例:

DFS 在访问图中某一起始顶点 v 后,由 v 出发,访问它的任一邻接顶点 w1;再从 w1 出发,访问与 w1邻 接但还没有访问过的顶点 w2;然后再从 w2 出发,进行类似的访问,… 如此进行下去,直至到达所有的邻接顶点都被访问过的顶点 u 为止。

接着,退回一步,退到前一次刚访问过的顶点,看是否还有其它没有被访问的邻接顶点。如果有,则访问此顶点,之后再从此顶点出发,进行与前述类似的访问;如果没有,就再退回一步进行搜索。重复上述过程,直到连通图中所有顶点都被访问过为止。

详细介绍:深度优先搜索

 

算法七:BFS(广度优先搜索)

广度优先搜索算法(Breadth-First-Search),是一种图形搜索算法。简单的说,BFS是从根节点开始,沿着树(图)的宽度遍历树(图)的节点。如果所有节点均被访问,则算法中止。BFS同样属于盲目搜索。一般用队列数据结构来辅助实现BFS算法。

算法步骤:

1. 首先将根节点放入队列中。

2. 从队列中取出第一个节点,并检验它是否为目标。

  • 如果找到目标,则结束搜寻并回传结果。
  • 否则将它所有尚未检验过的直接子节点加入队列中。

3. 若队列为空,表示整张图都检查过了——亦即图中没有欲搜寻的目标。结束搜寻并回传“找不到目标”。

4. 重复步骤2。

Animated_BFS

详细介绍:广度优先搜索

算法八:Dijkstra算法

戴克斯特拉算法(Dijkstra’s algorithm)是由荷兰计算机科学家艾兹赫尔·戴克斯特拉提出。迪科斯彻算法使用了广度优先搜索解决非负权有向图的单源最短路径问题,算法最终得到一个最短路径树。该算法常用于路由算法或者作为其他图算法的一个子模块。

该算法的输入包含了一个有权重的有向图 G,以及G中的一个来源顶点 S。我们以 V 表示 G 中所有顶点的集合。每一个图中的边,都是两个顶点所形成的有序元素对。(uv) 表示从顶点 u 到 v 有路径相连。我们以 E 表示G中所有边的集合,而边的权重则由权重函数 wE → [0, ∞] 定义。因此,w(uv) 就是从顶点 u 到顶点 v 的非负权重(weight)。边的权重可以想像成两个顶点之间的距离。任两点间路径的权重,就是该路径上所有边的权重总和。已知有 V 中有顶点 s 及 t,Dijkstra 算法可以找到 s 到 t的最低权重路径(例如,最短路径)。这个算法也可以在一个图中,找到从一个顶点 s 到任何其他顶点的最短路径。对于不含负权的有向图,Dijkstra算法是目前已知的最快的单源最短路径算法。

算法步骤:

1. 初始时令 S={V0},T={其余顶点},T中顶点对应的距离值

若存在<V0,Vi>,d(V0,Vi)为<V0,Vi>弧上的权值

若不存在<V0,Vi>,d(V0,Vi)为∞

2. 从T中选取一个其距离值为最小的顶点W且不在S中,加入S

3. 对其余T中顶点的距离值进行修改:若加进W作中间顶点,从V0到Vi的距离值缩短,则修改此距离值

重复上述步骤2、3,直到S中包含所有顶点,即W=Vi为止

Dijkstra_Animation

详细:Dijkstra算法

算法九:动态规划算法

动态规划(Dynamic programming)是一种在数学、计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。 动态规划常常适用于有重叠子问题和最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法。

动态规划背后的基本思想非常简单。大致上,若要解一个给定问题,我们需要解其不同部分(即子问题),再合并子问题的解以得出原问题的解。 通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量: 一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。 这种做法在重复子问题的数目关于输入的规模呈指数增长时特别有用。

关于动态规划最经典的问题当属背包问题。

算法步骤:

1. 最优子结构性质。如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。

2. 子问题重叠性质。子问题重叠性质是指在用递归算法自顶向下对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,只是在表格中简单地查看一下结果,从而获得较高的效率。

详细参考:

从全球导航到输入法:谈谈动态规划

动态规划

算法十:朴素贝叶斯分类算法

朴素贝叶斯分类算法是一种基于贝叶斯定理的简单概率分类算法。贝叶斯分类的基础是概率推理,就是在各种条件的存在不确定,仅知其出现概率的情况下,如何完成推理和决策任务。概率推理是与确定性推理相对应的。而朴素贝叶斯分类器是基于独立假设的,即假设样本每个特征与其他特征都不相关。

朴素贝叶斯分类器依靠精确的自然概率模型,在有监督学习的样本集中能获取得非常好的分类效果。在许多实际应用中,朴素贝叶斯模型参数估计使用最大似然估计方法,换言之朴素贝叶斯模型能工作并没有用到贝叶斯概率或者任何贝叶斯模型。

尽管是带着这些朴素思想和过于简单化的假设,但朴素贝叶斯分类器在很多复杂的现实情形中仍能够取得相当好的效果。

详细参考:

贝叶斯网络

朴素贝叶斯分类算法

本文链接:程序员必须知道的10大基础实用算法及其讲解

出处:快课

转载请保留出处链接,谢谢!

摘自:http://www.cricode.com/2001.html

 

Vysor – 无需 root,用 Chrome 完全控制 Android 设备

Vysor是一款 Chrome 应用,能够在 Chrome 里通过 USB 直接控制 Android 设备,无需 root。@Appinn

Vysor 的设置非常简单,只需要在 Chrome 里安装 Vysor,打开 Android 设备的 USB 调试模式,用 USB 线连接电脑与 Android 设备,就可以控制了。

在 Chrome 里,你能实时看到 Android 的界面,并且可以通过鼠标拖动、点击屏幕,还有其他快捷键:

  • ESC 返回按钮
  • F1 菜单按钮
  • Home 返回桌面
  • 鼠标右键 返回按钮
  • 鼠标中建桌面

第一次连接 Vysor,会自动在 Android 设备中安装一个应用,然后点击信任连接的电脑,就能在 Chrome 操作了,非常简单。

而在连接成功后,你完全可以将 Android 设备放到一边,Vysor 支持点亮屏幕(只需在黑屏上点一下鼠标右键),滑动输入密码,键盘打字,如果再配合PushBullet 将系统通知推送到 Chrome 里,真的 Android 与 电脑合一了…

鉴于需要安装 Chrome 应用,推荐个工具访问 Chrome 网上应用店。

青小蛙使用体验,Chrome 端的显示比较顺滑,处于完全可以接受的状态,两端几乎实时同步,没有延时。

Android Studio常用快捷键

[Android Studio] Android Studio常用快捷键

(会持续更新)这边讲的常用快捷键是指做完Keymap到Eclipse后的,不是纯Android Studio的,这边主要讲下比较常用的一些快捷键:

Ctrl+O:快捷查找当前类中的函数,变量

Alt+Enter:导入包

Ctrl+E:查看最近打开过的文件

Ctrl+Shift+E:查看最近编辑过的文件

Ctrl+G / Ctrl+Alt+Shift+G:查询变量或者函数或者类在哪里被使用或被调用,后者是前者的复杂表现,可以选择查询范围等。

Alt+H:查找功能,全局查找

F4:查看类继承关系

F2:查看文档说明(函数使用说明)

double Shift:全局查找,这个查看和Alt+H稍稍有些不同,这个是全局文件查找,到文件名称层面。

Ctrl+Shift+R:快速定位到你所想打开的文件。

Ctrl+K:选中一个变量后,快速定位到下一个使用该变量的地方(不过这个快捷键现在还存在一些bug,具体请看:Android Studio keymap到Eclipse后,查找下一个相同变量快捷键Ctrl+K失效

Alt+↑:光标所在位置那行代码往上移动

Alt+↓:光标所在位置那行代码往下移动

Ctrl+D:删除光标所在位置那行代码

Ctrl+X:剪切光标所在位置那行代码

Alt+Shift+↓/Ctrl+C:复制光标所在行代码到下一行

Ctrl+Shift+R:修改名称

Alt+←:后退,定位到上个查看或者编辑的地方

Alt+→:往前定位,比如你定位到上个点后,想回去,就可以用这个快捷键

Ctrl+/:当行注释,反注释再按一次即可

Ctrl+Shift+/:模块注释,反注释再按一次即可,注意这边的”/“不能用小键盘的

Ctrl+Shift+小键盘/:折叠代码(Ctrl+Shift+小键盘*这个不灵了,今天没空了,后面会针对这个问题做解决,并更新上来),当然笔记本没小键盘,你可以自己改快捷键

Ctrl+Alt+S:打开settings界面

Ctrl+Alt+Shift+S:打开Project Structure界面

Alt+Shift+X:运行(Run)

Alt+Shift+D:调试运行(Debug)

Ctrl+F9:编译工程

Ctrl+Shift+K:push文件到Server(git)

Debug类快捷键

F5:但不调试进入函数内部。

F7:由函数内部返回调用处。

F8:执行到下一个断点,没断点则执行完成。

Ctrl+Alt+F8/双击鼠标:直接查看选中位置的值,这两个快捷键稍稍有点区别,具体区别请看这:Android Studio 调试过程中快捷查看断点处变量值(Ctrl+Shift+I无效)?

这里有一个Android Studio的新的快捷功能,查看当前类中有哪些函数变量没被用到,哪些写法不合理。Eclipse没有的,很有用,下图中Inspect Code with Editor Settings就是是,你可以自己配置你所想用的快捷键,配置过程中,如果发现你想配置的快捷键被使用了,怎么看明白和哪些冲突,怎么解决,请戳这:Android Stuido如何查看快捷键冲突?

分类: Android Pro

摘自:http://www.cnblogs.com/0616–ataozhijia/p/3870064.html

这些小工具让你的Android开发更高效

本文为作者「Tikitoo」投稿,应该多少受我点影响,Tikitoo也是一位自学的Android工程师,并且完全通过自学找到一份还不错的工作。互联网爱好者,并且是简书专题的运营者,点击「阅读原文」可以跳转到作者的博客。

在做Android 开发过程中,会遇到一些小的问题,虽然自己动手也能解决,但是有了一些小工具,解决这些问题就得心应手了,今天就为大家推荐一下Android 开发遇到的小工具,来让你的开发更高效。

1. Vysor

Vysor 是一个可以将手机的屏幕投影到电脑上,当然也可以操作,当我们做分享或者演示的时候,这个工具起到了作用。

2. Vector Asset

Android Studio 在1.4 支持了VectorAsset,所谓VectorAsset;它可以帮助你在Android 项目中添加Material Icon 和SVG 图片来作为一个Drawable 资源来使用。不过唯一一点的缺陷就是没有搜索功能,如果你想精心挑选Material Icon ,可以打来网页版来选择,也可以下载SVG 和Png 格式。对于VectorAsset 的好处,它的文件更小,更容易适配不同的屏幕。

3. Stetho

Stetho 是一个Android 开发调试小工具,它可以让你使用Chrome Develop Tools 来可以来查看Sqlite 数据库和SharePreferences,而且可以查看网络连接的数据。在Chrome 输入框输入「chrome://inspect」,点击inspect 就可以开始了。如果使用OkHttp 需要添加拦截器StethoInterceptor。

4. OctoTree

OctoTree 是一个浏览器插件,它可以让你在Github 看代码时,左边栏会出现一个树状结构,就像我们在IDE 一样。当我们看一个项目的结构,或者想看具体的某个文件,这样就会很方便。

5. Chrome ADB

Chrome ADB 是一个使用Chrome 来调试Android 的小工具,它除了提供了安装,卸载,清理数据的基本功能,而且还提供了主页,返回,锁屏的虚拟键功能,也可以看各个应用占用的内存(不得不点名批评一下微信,关闭都还占用100M 内存,不知道你要干嘛)。它还有Android 的App,两者交互一定更有意思。

6. TinyPng

TinyPng 是一个图片压缩工具,可能有些人感觉这个工具应该给设计师使用,我觉得也是。不过有些时候,设计师给你出了个1920* 1080 的启动页,一张图片,1M 左右,我也是泪奔了,感觉设计师说话的时间,估计我们都压缩完了,自己动手,丰衣足食。而且它还提供了API,对不同语言都还有提供了插件,比如Java 就提供了Maven 的支持。

7. PostMan

PostMan 是一个API 调试工具,它提供Chrome App 和Mac App,除了提供基本的API 测试功能, 它还可以添加各种的Auth 认证,响应结果可以选择不同类型,比如HTML,JSON 等,可以设置通用的Header,还可以将之前测试的添加到一个集合,而且也可以同步到服务器,而且最近还添加了团队服务,想想服务器端写完测试你就能看到结果,而不是给你API 文档(当然API 文档还是要有的),这画面太美,我不敢想象。当然它的功能也远远不止这些,它还有专业版,想尝试更多的东西可以体验一下。

8. Genymotion 虚拟机

刚开始做开发的时候,每次使用官方的虚拟机,都想吐槽一下,但是发现了Genymotion 之后,这一切都变化了,它的速度几乎可以和真机媲美了,当然如果有真机,当然还是推荐使用真机测试。据说官方模拟器2.0 很快,不知道是不是又吹牛逼。

9. Json2POJO

Json2POJO 是可以将一个Json 字符串转换成Java 的POJO 类的网页工具,而且可以选择转换器,比如我们使用Retrofit 可以选择Jackson,Gson,而且可以选择重写get,set 方法,还有hashcode,equals 和toString 方法,可以省去了不少手写的时间。

10. Android Pixel

AndroidPixel 是一个简单的将不同的分辨率的换算工具,只要你有一个尺寸的大小,其他的尺寸大小就可以得出,当然dp 这样的单位,可以解决一部分问题,但是大多还要需要微调,这时AndroidPixel 就起到了作用。这个工具来自上一个公司同事告诉我的。

11. Android Arsenal

Android Arsenal 主要是推荐Github 上一些流行的Android 开源项目,基本上最近热门的Android 开源项目都会出现在这里,它还对不同类库进行了分类。

12. AndroidAssetStudio

Android Asset Studio 是一个在线制作工具,它可以制作Iocn,ActionBar,点9 图等等,简单的操作,大大提高了我们开发的效率。

13. WiFi ADB

WiFi ADB 是一个通过无线网络来使电脑和手机连接的手机App(可以去Google Play 搜索类似的),当我们做测试的时候,只需在手机上打开,电脑只需在命令行输入「adb connect xxx.xxx.xxx.xxx:5555」,电脑可以连接手机,就可以通过无线网络来调试开发的应用。

14. ES Explorer

ES Explorer 是一款文件管理器,但实际它又不仅仅是一款文件管理器,在获得Root 之后,它的功能更强大了,它可以浏览受限制的文件目录;而且提供了一系列小工具,比如下载器;还有集成了众多云储存服务。

微信公众号不支持链接,可以点击「阅读原文」查看。

友情提示:

之前的书籍奖励的两位同学「纪红阳」、「.」,没错,第二个中奖的用户微信名称就是一个点,不知道你们给我回复了收获地址被淹没了还是压根忘记回复了,请加我微信吧「stormzhang」,微信好友已经太多了,其他人一概不加,忘见谅!

 

摘自:http://mp.weixin.qq.com/s?__biz=MzA4NTQwNDcyMA==&mid=402858357&idx=1&sn=5dd38f4dcc5d7680e6daf7b3d1105b63#rd

成功者是如何战胜生命中的忧虑?

繁重的生活、工作压力让每个人都能感受到情绪的存在,人们都想摆脱不良情绪,却在很多时候都被情绪牵着鼻子走。如何能够面对现实,活得开心?今天“读写客”推荐美国成功学大师戴尔 · 卡耐基文章,探讨人性的优点与缺点。

1871年春,一个年轻人拿起一本书,书中21个词汇对他的未来产生了深刻的影响。他是加拿大蒙特利尔综合医院的一个学生。他为期末考试烦恼,为无所事事烦恼,为何去何从烦恼,为怎么实习烦恼,为如何谋生烦恼。

得益于1871年读过的那21个词汇,这位年轻的医学院学生成为他那一代人中最有声望的内科专家。他创建了蜚声世界的霍普金斯医学院,他成为剑桥大学的皇家教授——那是大英帝国授给医学界人士的最高荣誉。他被英国国王封为爵士。他去世时,关于他生平事迹的书籍足有整整两卷,长达1466页。他是威廉·奥斯勒爵士。1871年春他读过的那21个词汇出自托马斯·卡莱尔,这些词汇让他在此后的人生中远离了烦恼:“我们的主要任务不是遥望远方的黑暗,而是关注于眼前。”

42年后一个微风和煦的晚上,耶鲁校园里的郁金香迎着春风盛放,就是这个人——威廉·奥斯勒爵士,对耶鲁学子们发表演说。他告诉这些学生,像他那样一个任教于四所大学、写过一部畅销书的教授,理应有一个“卓尔不凡的大脑”。他宣称,事实并非如此。他说,熟悉他的人都知道,他的脑子“平庸之极”。

那么,什么才是他的成功秘诀呢?他解释说,他的成功归功于他所说的活在“日密舱”里。这话怎么讲?在耶鲁演讲前几个月,威廉·奥斯勒爵士搭乘一艘邮轮横渡大西洋。船长站在驾驶舱里,按动一枚按钮——机器“叮当”一声,瞬间变戏法似的,轮船一些部件立即纷纷关闭,然后轮船进入“水密舱”。

“现在,你们每一人——”威廉·奥斯勒博士对这些耶鲁学子说,“你们每个人的身体都是一部比巨型邮轮更了不起的组织,航程也更远大。我要告诫你们,学会控制,生活在‘日密舱’,这才是航行最安全的保障。去驾驶舱看看,至少确保主要隔水舱运行正常。

在你人生的每一个阶段,按一下按钮,把“过去”——死去的昨天关在外面;接着,按另一个按钮,一个金属舱壁再次关上,那是“未来”——还未诞生的明天;这样你就安全了——你的今天就安全了!

把未来关闭得和过去一样严严实实吧……未来就是今天……永远就没有个什么明天。人类的救赎就在今天。一个对未来担惊受怕的人,精力的损耗、内心的压力和精神上的烦恼会像咬尾的蛇一样紧追不舍……那么,将过去和未来的大水壁关闭了,养成这样一种习惯——活在当下的‘日密舱’中!”

奥斯勒博士的意思莫非是我们完全不必为了明天而未雨绸缪?不,完全不是。在那场演讲中他接着说过,对明天最好的准备方式就是集中你们所有的智慧和热情,把今天的事情做得无可挑剔。这是迎接明天唯一最可行的办法。

在耶鲁大学,威廉·奥斯勒爵士呼吁学生按耶稣基督祷告的那样开始每一天:“把今天的面包给我们。”

记住,这句祷文只要求今天的面包,而没有抱怨我们昨天吃下去的旧面包,也没有说:“主啊,近来小麦带干旱,可能还会干旱,明天秋天我可去哪儿找面包啊?——或者我要是失业了,主啊,我去哪儿找吃的啊!”

没有,这句祷文只教诲我们找今天的面包。因为,今天的面包可能是你唯一能吃到口的。

多年前,一个身无分文的哲学家在一片贫瘠的土地上晃荡,那儿的人生活得很艰辛。一天,人们在一座山丘上围绕着哲学家,他发表了一场演说,在人类历史上其引用率可能空前绝后。他的演说包含26个词汇,回荡了几个世纪之久:“不要去想什么明天,因为明日自有明日的想法,活好今天才是正道。”

很多人反对耶稣的这句话:“别想明天的事情。”他们将这句话斥之为完美建议和神秘主义。他们说:“为了保护家人,我必须买保险;为了养老,我必须攒钱;未来将来,我必须早做打算。”

没错!你当然必须。实际上,耶稣这句话是300年前翻译的,在詹姆斯王朝时的意思和今天的意思并不一样。300年前,thought这个词的意思常常指anxiety(焦虑、忧虑)。现代版《圣经》对耶稣这句话的引用更为准确:“别为明日忧。”

是的,无论如何,想着明天;为了明天未雨绸缪,但别因为明天而烦恼。

第二次世界大战期间,我们的军事领导人为明天做了谋划,但他们无法承受烦恼之重。

“我为最好的将士配备了我们所能提供的最好武器。”指挥美国海军的欧内斯特·J.詹姆斯上将这样说,“还给了他们执行使命的最佳方案,我能做的就是这些。”

“如果一艘舰艇被击沉。”欧内斯特·J.詹姆斯上将接着说,“我没办法把它打捞起来。如果一定会沉没,我也束手无策。我能更有效地为明天的事情工作,而不是为昨天的事情懊恼不已。另外,如果我任由那些烦恼缠住我,我也扛不住。”

无论战争时期还是和平时期,乐观思维和悲观思维最大的区别在于——乐观思维能理顺事情的前因后果,取得符合逻辑、建设性的计划;悲观思维则经常引起紧张和神经崩溃。

我荣幸地采访过阿瑟·海斯·苏兹伯格,1935到1961年间,他是世界上最有影响力的报纸之一《纽约时报》的出版人。苏兹伯格先生告诉我,当“二战”硝烟弥漫欧洲时,他惊慌失措,对未来太焦虑,以至于几乎无法入眠。他常常半夜起床,取出画布和油画笔,看着镜中的自己,试图画一幅自画像。其实他根本不会画画,但为了驱逐焦虑,还是画了。苏兹伯格先生告诉我,他从来无法祛除他的焦虑,直到他将一首赞美诗中的词汇作为自己的座右铭——“一步对我足够”。

光明指引……

我紧随你的脚步:

我勿需眺望远景;

一步对我足够。

大约同一时间欧洲某个地方,一个穿军服的年轻人也学到了人生这一课。他的名字叫特德·本杰明诺,来自马里兰州的巴尔的摩,他的焦虑使他患上了一级战斗疲劳症。

“1945年4月。”本杰明诺写道,“我的焦虑发展到了医生所说的‘痉挛性结肠炎’——那是一种能引起剧烈疼痛的病。如果战争不是那时结束,我整个人肯定早就垮了。”

本杰明诺接着说:“我当时已经筋疲力尽了。我是墓地登记员,隶属于第94步兵师,是没有军衔的那种军官。我的职责就是对在各项行动中所有阵亡、失踪和负伤住院的人员建立档案,并保存这些记录。我还必须协助把那些在战斗最激烈时阵亡后匆匆浅埋的军人尸体——无论是盟军还是敌军的,挖出来进行深埋。我还必须将阵亡军人的个人物品收集起来,负责寄送给他们的家人或近亲;对这些物品,他们非常珍视。

我担心不停,生怕出什么纰漏,引起尴尬。我担心我能否完成这任务。我担心我能不能活到抱一抱我那唯一的儿子的那一刻——他才16个月大,我还没见过呢。我焦虑和疲惫得体重掉了34磅。我狂躁不安,距疯掉只一步之遥。我看着自己的双手,发现它们简直就是皮包骨。一想起回家时成了个废人,我就魂飞魄散。我崩溃了,像孩子似的哭泣。我脆弱极了,一旦独处我就泪流满面。在巴尔吉战役后不久的那一阵,我哭得太多了,连做一个正常人的希望都差点放弃。

“最后我去了部队医院,一位军医给了我一些建议——这些建议彻底改变了我的生活。在做了彻底体检后他告诉我,我的问题是心理上的。他说:‘特德,我希望你把自己的生命看成一个计时沙漏器。你知道,在沙漏器顶部有不计其数的沙粒,所有沙粒都会缓慢而均匀地穿过容器中部的狭窄瓶颈;除非把沙漏弄坏了,你我没有任何办法能多让一粒沙子经过瓶颈。你,我,或任何别的人,都像沙漏器一样。每天早上一起床,我们会觉得有几百个任务需要当天完成;然而,如果我们不按部就班一个一个地来——就像沙粒通过沙漏器的瓶颈一样,慢慢地来,有条不紊地来;不论我们的身体还是心理,都会垮掉的。’

“自从军医给我上了这堂难忘的课那天后,我便开始践行这些哲学。‘一次一粒沙……一次一件事’,这个忠告在战争期间不仅挽救了我的身体,还挽救了我的心灵;对我目前在广告印务和平面印务公司担任的公共关系和广告经理这个职务,也很有帮助。我发现,那些战争时期出现的问题,在职场中同样出现了:太多事情需要马上处理——而时间却太紧。

譬如,库存太低,新表格需要填写,进货需要安排,地址要修改,办公室开张关张,等等。我记起那位军医的话‘一次一粒沙……一次一件事’,才没有方寸大乱。通过不断温故这句话,我以一种有效得多的方式完成了任务,那种在战场上差点毁了我的迷茫和紊乱感烟消云散。”

关于当代生活方式,最令人瞠目结舌的观点之一是:我们的医院一度把一半病床留给了各种精神和心理病人——无数个“昨天”累积起来的千钧重压和令人忧惧的“明天”,终于将这些人压垮。然而,这类病人绝大部分原本并不需要住院,他们原本可以过着幸福有意义的生活——如果他们一早就知道耶稣所说的“别为明日忧”或者威廉·奥斯勒爵士说的“活在日密舱”的道理。

此刻,你我正好同时站在两种永恒的交会点:不堪回首的浩瀚而永恒的历史以及连通永恒的未来。我们不可能置身一种永恒里——不可能!甚至不可能活在被分割的一秒钟之内。如果非要去折腾,必然身心俱毁。所以,还是知足常乐,活在我们唯一能够存在的时间内:从现在起,直到上床就寝。

罗伯特·路易斯·斯蒂文森这样说:“无论负担多么沉重,任何人都能撑一天;无论工作多么艰难,任何人都能坚持一天;从朝霞到日暮,任何人都能生活在甜蜜、耐心、珍爱和纯洁之中。这就是生活的全部要义。”

是的,这就是生活对我们的要求。但对于密歇根州萨基纳多的E.K.谢尔兹太太而言,在学会“活在今天”之前,她陷入了绝望——甚至处于自杀的边缘。谢尔兹太太向我讲述她的故事时,这样说道:

“1937年,我丈夫去世了。我极度抑郁——几乎不名一文。我给我的前雇主——堪萨斯市洛奇福勒公司的里奥·洛奇先生写了一封信,恢复了我以前的工作。以前我是以去乡村和小镇推销《世界百科全书》为生。两年前,我丈夫生病,我卖掉了我的汽车。恢复工作后,我想方设法凑齐了买一辆二手车的首付款。我曾以为,重操旧业有助于缓解我的抑郁症,但孤身一人开车,孤身一人吃饭简直让我难以忍受。有些地方生意不好做,我觉得很难赚够买车钱——尽管那也不算什么大钱。

“1938年春,我去密苏里州的维塞里斯卖书。那儿的学校很穷,路很旧。我如此孤独和沮丧,甚至想到了自杀。我的日子毫无奔头了,我恐惧明天早起面对生活。我担心一切:还不起购车款,付不起房租,吃不起饭,身体日渐垮了却看不起病……只有两个想法阻止了我的自杀:我姐姐会伤心欲绝,我没钱支付我的葬礼。

“后来的一天,我看到的一篇文章将我从沮丧里拽了出来,并给了我活下去的勇气。其中一句话非常鼓舞人,我永远不会忘记文章中这句话对我的恩典。这句话是这样的:‘对聪明人来说,每一天都是新生活。’我把那句话打印下来,粘贴在汽车挡风玻璃上,这样,开车时每一分钟都会看到。我学会了忘记昨天,也不想明天。每天早晨,我都对自己说:‘今天就是新生活。’我发现,每一次活过一天不算太难。

“我战胜了我的孤独恐惧,我的需求恐惧。现在的我很开心,对生活充满了热情和爱。我现在明白,无论今后生活怎么变幻,我都不会再恐惧了;我现在明白,我不必为未来恐惧;我现在明白,我能一次活好一天;我现在明白‘对聪明人来说,每一天都是新生活’的含义。”

底特律不久前去世的爱德华·S.伊文斯先生,在领悟“生活就是活在每一天、每一分钟的肌理中”这句话之前,差一点杀了自己。爱德华·S.伊文斯幼时家境贫寒,他挣的第一分钱是做报童,随后在杂货店打工。再后来,为了养活家里七个人,他去做图书馆助理管理员。尽管薪水少得可怜,他却担心丢掉饭碗。八年后,他终于鼓起勇气创业。

但一旦开始,他凭东拼西凑的50美元老本,仅在第一年就赚了两万美元!然后是一场变故,一场要命的变故。他为一个朋友做贷款担保,这个朋友却破产了。很快,祸不单行——他存款的那家银行倒闭了。爱德华除了将赚到的每一分钱全部亏掉,还倒欠一万六!他无法承受这个打击。

他告诉我:“我寝食难安,我很奇怪地得了一种病——焦虑症。焦虑,我的病完全是焦虑引起的。有一天当我走在街上时,走不动了,昏倒在人行道上。我被送到病床上,我身上长满了大疡肿。大疡肿向体内发展,直到我一病不起,备受折磨。我的身体一天天虚弱下去。最后,大夫告诉我只有两个礼拜可活。我吓坏了,写好遗书,躺回病床等待末日来临。现在,挣扎和焦虑都无济于事。于是,我放弃了,放松了,睡着了。此前几个礼拜,我没有一天睡满过两小时;现在呢,反正尘世间的一切都已了结,我睡得跟个婴儿似的。我的精疲力竭开始逆向发展,我的胃口回来了,我的体重居然增加了。

“几周后,我能拄着拐杖走路了。六周后,我就回去工作了。我曾经一年赚了两万美元,现在找了个每周付我30美元的工作我也很开心。我的工作是销售——汽车装船运输时,需要在车后轮上装阻隔物——我就卖那种阻隔物。我现在汲取了以前的教训。对过去,我无怨无悔;对将来,也从容坦荡。我将自己所有的时间、精力和热情全部倾注于销售工作中。”

爱德华·S.伊文斯的事业从此突飞猛进。几年后,他成为伊文斯产品公司老总,公司在纽约证券交易所上市好几年了。如果你飞临格陵兰岛,可能会降落在以他名字命名的伊文斯机场。当然,如果伊文斯不能领悟“活在‘日密舱’”的含义,他绝不会取得这些成就。

你可能会想起怀特·奎恩说过的那句话:“给你昨天的果酱,给你明天的果酱,但今天的果酱想都别想。”

此句话比喻那些永远无法实现的诺言和空头支票。

我们大多数人都喜欢为昨天耿耿于怀,为明天惴惴不安,却从来不抓住眼前的醇厚的“果酱”。

本文选自《人性:优点与弱点》,北京大学出版社

淘宝大秒系统设计详解

导读:最初的秒杀系统的原型是淘宝详情上的定时上架功能,由于有些卖家为了吸引眼球,把价格压得很低。但这给的详情系统带来了很大压力,为了将这种突发流量隔离,才设计了秒杀系统,文章主要介绍大秒系统以及这种典型读数据的热点问题的解决思路和实践经验。

一些数据

大家还记得2013年的小米秒杀吗?三款小米手机各11万台开卖,走的都是大秒系统,3分钟后成为双十一第一家也是最快破亿的旗舰店。经过日志统计,前端系统双11峰值有效请求约60w以上的QPS ,而后端cache的集群峰值近2000w/s、单机也近30w/s,但到真正的写时流量要小很多了,当时最高下单减库存tps是红米创造,达到1500/s。

热点隔离

秒杀系统设计的第一个原则就是将这种热点数据隔离出来,不要让1%的请求影响到另外的99%,隔离出来后也更方便对这1%的请求做针对性优化。针对秒杀我们做了多个层次的隔离:

  • 业务隔离。把秒杀做成一种营销活动,卖家要参加秒杀这种营销活动需要单独报名,从技术上来说,卖家报名后对我们来说就是已知热点,当真正开始时我们可以提前做好预热。
  • 系统隔离。系统隔离更多是运行时的隔离,可以通过分组部署的方式和另外99%分开。秒杀还申请了单独的域名,目的也是让请求落到不同的集群中。
  • 数据隔离。秒杀所调用的数据大部分都是热数据,比如会启用单独cache集群或MySQL数据库来放热点数据,目前也是不想0.01%的数据影响另外99.99%。

当然实现隔离很有多办法,如可以按照用户来区分,给不同用户分配不同cookie,在接入层路由到不同服务接口中;还有在接入层可以对URL的不同Path来设置限流策略等。服务层通过调用不同的服务接口;数据层可以给数据打上特殊的标来区分。目的都是把已经识别出来的热点和普通请求区分开来。

动静分离

前面介绍在系统层面上的原则是要做隔离,接下去就是要把热点数据进行动静分离,这也是解决大流量系统的一个重要原则。如何给系统做动静分离的静态化改造我以前写过一篇《高访问量系统的静态化架构设计》详细介绍了淘宝商品系统的静态化设计思路,感兴趣的可以在《程序员》杂志上找一下。我们的大秒系统是从商品详情系统发展而来,所以本身已经实现了动静分离,如图1。

图片描述

图1 大秒系统动静分离
除此之外还有如下特点:

  • 把整个页面Cache在用户浏览器
  • 如果强制刷新整个页面,也会请求到CDN
  • 实际有效请求只是“刷新抢宝”按钮

这样把90%的静态数据缓存在用户端或者CDN上,当真正秒杀时用户只需要点击特殊的按钮“刷新抢宝”即可,而不需要刷新整个页面,这样只向服务端请求很少的有效数据,而不需要重复请求大量静态数据。秒杀的动态数据和普通的详情页面的动态数据相比更少,性能也比普通的详情提升3倍以上。所以“刷新抢宝”这种设计思路很好地解决了不刷新页面就能请求到服务端最新的动态数据。

基于时间分片削峰

熟悉淘宝秒杀的都知道,第一版的秒杀系统本身并没有答题功能,后面才增加了秒杀答题,当然秒杀答题一个很重要的目的是为了防止秒杀器,2011年秒杀非常火的时候,秒杀器也比较猖獗,而没有达到全民参与和营销的目的,所以增加的答题来限制秒杀器。增加答题后,下单的时间基本控制在2s后,秒杀器的下单比例也下降到5%以下。新的答题页面如图2。

图片描述

图2 秒答题页面
其实增加答题还有一个重要的功能,就是把峰值的下单请求给拉长了,从以前的1s之内延长到2~10s左右,请求峰值基于时间分片了,这个时间的分片对服务端处理并发非常重要,会减轻很大压力,另外由于请求的先后,靠后的请求自然也没有库存了,也根本到不了最后的下单步骤,所以真正的并发写就非常有限了。其实这种设计思路目前也非常普遍,如支付宝的“咻一咻”已及微信的摇一摇。

除了在前端通过答题在用户端进行流量削峰外,在服务端一般通过锁或者队列来控制瞬间请求。

数据分层校验

图片描述

图3 分层校验
对大流量系统的数据做分层校验也是最重要的设计原则,所谓分层校验就是对大量的请求做成“漏斗”式设计,如图3所示:在不同层次尽可能把无效的请求过滤,“漏斗”的最末端才是有效的请求,要达到这个效果必须对数据做分层的校验,下面是一些原则:

  • 先做数据的动静分离
  • 将90%的数据缓存在客户端浏览器
  • 将动态请求的读数据Cache在Web端
  • 对读数据不做强一致性校验
  • 对写数据进行基于时间的合理分片
  • 对写请求做限流保护
  • 对写数据进行强一致性校验

秒杀系统正是按照这个原则设计的系统架构,如图4所示。

图片描述

图4 秒杀系统分层架构
把大量静态不需要检验的数据放在离用户最近的地方;在前端读系统中检验一些基本信息,如用户是否具有秒杀资格、商品状态是否正常、用户答题是否正确、秒杀是否已经结束等;在写数据系统中再校验一些如是否是非法请求,营销等价物是否充足(淘金币等),写的数据一致性如检查库存是否还有等;最后在数据库层保证数据最终准确性,如库存不能减为负数。

实时热点发现

其实秒杀系统本质是还是一个数据读的热点问题,而且是最简单一种,因为在文提到通过业务隔离,我们已能提前识别出这些热点数据,我们可以提前做一些保护,提前识别的热点数据处理起来还相对简单,比如分析历史成交记录发现哪些商品比较热门,分析用户的购物车记录也可以发现那些商品可能会比较好卖,这些都是可以提前分析出来的热点。比较困难的是那种我们提前发现不了突然成为热点的商品成为热点,这种就要通过实时热点数据分析了,目前我们设计可以在3s内发现交易链路上的实时热点数据,然后根据实时发现的热点数据每个系统做实时保护。 具体实现如下:

  • 构建一个异步的可以收集交易链路上各个中间件产品如Tengine、Tair缓存、HSF等本身的统计的热点key(Tengine和Tair缓存等中间件产品本身已经有热点统计模块)。
  • 建立一个热点上报和可以按照需求订阅的热点服务的下发规范,主要目的是通过交易链路上各个系统(详情、购物车、交易、优惠、库存、物流)访问的时间差,把上游已经发现的热点能够透传给下游系统,提前做好保护。比如大促高峰期详情系统是最早知道的,在统计接入层上Tengine模块统计的热点URL。
  • 将上游的系统收集到热点数据发送到热点服务台上,然后下游系统如交易系统就会知道哪些商品被频繁调用,然后做热点保护。如图5所示。

图片描述

图5 实时热点数据后台
重要的几个:其中关键部分包括:

  • 这个热点服务后台抓取热点数据日志最好是异步的,一方面便于做到通用性,另一方面不影响业务系统和中间件产品的主流程。
  • 热点服务后台、现有各个中间件和应用在做的没有取代关系,每个中间件和应用还需要保护自己,热点服务后台提供一个收集热点数据提供热点订阅服务的统一规范和工具,便于把各个系统热点数据透明出来。
  • 热点发现要做到实时(3s内)。

关键技术优化点

前面介绍了一些如何设计大流量读系统中用到的原则,但是当这些手段都用了,还是有大流量涌入该如何处理呢?秒杀系统要解决几个关键问题。

Java处理大并发动态请求优化

其实Java和通用的Web服务器相比(Nginx或Apache)在处理大并发HTTP请求时要弱一点,所以一般我们都会对大流量的Web系统做静态化改造,让大部分请求和数据直接在Nginx服务器或者Web代理服务器(Varnish、Squid等)上直接返回(可以减少数据的序列化与反序列化),不要将请求落到Java层上,让Java层只处理很少数据量的动态请求,当然针对这些请求也有一些优化手段可以使用:

  • 直接使用Servlet处理请求。避免使用传统的MVC框架也许能绕过一大堆复杂且用处不大的处理逻辑,节省个1ms时间,当然这个取决于你对MVC框架的依赖程度。
  • 直接输出流数据。使用resp.getOutputStream()而不是resp.getWriter()可以省掉一些不变字符数据编码,也能提升性能;还有数据输出时也推荐使用JSON而不是模板引擎(一般都是解释执行)输出页面。

同一商品大并发读问题

你会说这个问题很容易解决,无非放到Tair缓存里面就行,集中式Tair缓存为了保证命中率,一般都会采用一致性Hash,所以同一个key会落到一台机器上,虽然我们的Tair缓存机器单台也能支撑30w/s的请求,但是像大秒这种级别的热点商品还远不够,那如何彻底解决这种单点瓶颈?答案是采用应用层的Localcache,即在秒杀系统的单机上缓存商品相关的数据,如何cache数据?也分动态和静态:

  • 像商品中的标题和描述这些本身不变的会在秒杀开始之前全量推送到秒杀机器上并一直缓存直到秒杀结束。
  • 像库存这种动态数据会采用被动失效的方式缓存一定时间(一般是数秒),失效后再去Tair缓存拉取最新的数据。

你可能会有疑问,像库存这种频繁更新数据一旦数据不一致会不会导致超卖?其实这就要用到我们前面介绍的读数据分层校验原则了,读的场景可以允许一定的脏数据,因为这里的误判只会导致少量一些原本已经没有库存的下单请求误认为还有库存而已,等到真正写数据时再保证最终的一致性。这样在数据的高可用性和一致性做平衡来解决这种高并发的数据读取问题。

同一数据大并发更新问题

解决大并发读问题采用Localcache和数据的分层校验的方式,但是无论如何像减库存这种大并发写还是避免不了,这也是秒杀这个场景下最核心的技术难题。

同一数据在数据库里肯定是一行存储(MySQL),所以会有大量的线程来竞争InnoDB行锁,当并发度越高时等待的线程也会越多,TPS会下降RT会上升,数据库的吞吐量会严重受到影响。说到这里会出现一个问题,就是单个热点商品会影响整个数据库的性能,就会出现我们不愿意看到的0.01%商品影响99.99%的商品,所以一个思路也是要遵循前面介绍第一个原则进行隔离,把热点商品放到单独的热点库中。但是无疑也会带来维护的麻烦(要做热点数据的动态迁移以及单独的数据库等)。

分离热点商品到单独的数据库还是没有解决并发锁的问题,要解决并发锁有两层办法。

  • 应用层做排队。按照商品维度设置队列顺序执行,这样能减少同一台机器对数据库同一行记录操作的并发度,同时也能控制单个商品占用数据库连接的数量,防止热点商品占用太多数据库连接。
  • 数据库层做排队。应用层只能做到单机排队,但应用机器数本身很多,这种排队方式控制并发仍然有限,所以如果能在数据库层做全局排队是最理想的,淘宝的数据库团队开发了针对这种MySQL的InnoDB层上的patch,可以做到数据库层上对单行记录做到并发排队,如图6所示。

图片描述

图6 数据库层对单行记录并发排队
你可能会问排队和锁竞争不要等待吗?有啥区别?如果熟悉MySQL会知道,InnoDB内部的死锁检测以及MySQL Server和InnoDB的切换会比较耗性能,淘宝的MySQL核心团队还做了很多其他方面的优化,如COMMIT_ON_SUCCESS和ROLLBACK_ON_FAIL的patch,配合在SQL里面加hint,在事务里不需要等待应用层提交COMMIT而在数据执行完最后一条SQL后直接根据TARGET_AFFECT_ROW结果提交或回滚,可以减少网络的等待时间(平均约0.7ms)。据我所知,目前阿里MySQL团队已将这些patch及提交给MySQL官方评审。

大促热点问题思考

以秒杀这个典型系统为代表的热点问题根据多年经验我总结了些通用原则:隔离、动态分离、分层校验,必须从整个全链路来考虑和优化每个环节,除了优化系统提升性能,做好限流和保护也是必备的功课。

除去前面介绍的这些热点问题外,淘系还有多种其他数据热点问题:

  • 数据访问热点,比如Detail中对某些热点商品的访问度非常高,即使是Tair缓存这种Cache本身也有瓶颈问题,一旦请求量达到单机极限也会存在热点保护问题。有时看起来好像很容易解决,比如说做好限流就行,但你想想一旦某个热点触发了一台机器的限流阀值,那么这台机器Cache的数据都将无效,进而间接导致Cache被击穿,请求落地应用层数据库出现雪崩现象。这类问题需要与具体Cache产品结合才能有比较好的解决方案,这里提供一个通用的解决思路,就是在Cache的client端做本地Localcache,当发现热点数据时直接Cache在client里,而不要请求到Cache的Server。
  • 数据更新热点,更新问题除了前面介绍的热点隔离和排队处理之外,还有些场景,如对商品的lastmodifytime字段更新会非常频繁,在某些场景下这些多条SQL是可以合并的,一定时间内只执行最后一条SQL就行了,可以减少对数据库的update操作。另外热点商品的自动迁移,理论上也可以在数据路由层来完成,利用前面介绍的热点实时发现自动将热点从普通库里迁移出来放到单独的热点库中。

按照某种维度建的索引产生热点数据,比如实时搜索中按照商品维度关联评价数据,有些热点商品的评价非常多,导致搜索系统按照商品ID建评价数据的索引时内存已经放不下,交易维度关联订单信息也同样有这些问题。这类热点数据需要做数据散列,再增加一个维度,把数据重新组织。

作者简介:许令波,2009年加入淘宝,目前负责商品详情业务和稳定性相关工作,长期关注性能优化领域,参与了淘宝高访问量Web系统主要的优化项目,著有《深入分析Java Web技术内幕》一书。个人网站http://xulingbo.net

一些基于Kafka Connect的开源连接器

在Apache Kafka 0.9版本中,Kafka Connect特性被添加让Kafka可以建立可扩展和安全的流数据管道。下表中,Kafka Connector Hub列出了一些基于Kafka Connect建立的connectors。如果你发现新的,也可以联系confluent-platform@googlegroups.com添加。

Connector Name Owner Status
HDFS confluent-platform@googlegroups.com Confluentsupported
JDBC confluent-platform@googlegroups.com Confluentsupported
Debezium – CDC Sources debezium@gmail.com Community project
MongoDB Source a.patelli@reply.de
a.topchyan@reply.de
In progress
MQTT Source tomasz.pietrzak@evok.ly Community project
MySQL Binlog Source wushujames@gmail.com In progress
Twitter Source rollulus@xs4all.nl In progress
Cassandra Sink Cassandra Sink Community project
Elastic Search Sink ksenji@gmail.com Community project
Elastic Search Sink hannes.stockner@gmail.com In progress
Elastic Search Sink a.patelli@reply.de
a.topchyan@reply.de
In progress

责编/仲浩

摘自:http://geek.csdn.net/news/detail/57267