50天1个亿,不曾到过的世界-创业半年小结

 

2015年过完年,er又打来了电话,从去年开始,已经是第6次了,包包已经会走了,开始学会通过撒娇、大哭达到自己的目的。和er聊了1个小时,答应晚上和夫人商量一下,心已动摇。这个问题和夫人已讨论多次,还是在犹豫,不知是对未知的恐惧,还是对当下的不舍。

最终决定去上海,和er一起创业。梦想还是要有的,万一实现了呢。

选择离开

”橘子红了,是该摘了。“ -- 《橘子红了》

在腾讯的生活充实,有序,领导重视,同事nice,一切的一切都显示得让人无法离开。

创业是选择要未来,而不是现在--冯仑。

这样的当下,这样的现在,真的舍得?

和leader面谈、和总监面谈、和HR面谈、和GM面谈,惭愧,愧疚,不舍……

一切显示如此匆忙,在腾讯的日子越来越少,看着周围的同事都在忙活,心里不免有一些失落……

离别总是别样的风景,在腾讯的682天,2次晋升、3次发文奖励、1次优秀员工,得到了自己想得到的,遇见了自己该遇见的。在腾大7楼退掉工卡,慢慢走出腾讯大楼,回头看去,有些模糊了。

重新启程

”天青色等烟雨,而我在等你。“——《青花瓷》

3.31号,愚人节的前一天,从上海浦东机场转磁悬浮,5站地铁,到了世纪大道,在2号口见到了依稀有些丰满的er,在网上认识很多年,一直未曾见过面,总算见到活的张er。第一次见面,仿佛现实中认识了很多年,是如此熟悉。

到了办公室,略拥挤,er说已经在张罗新的办公场地了,先将就下,研发部20多人,移动开发,后台、前端、设计、测试。已经是下班时间了,还有一半的人在,有新版本准备上线。

之前已经了解过后端的代码了,对于数据库结构及代码基本已经摸清了,后面就是人员的磨合,对具体业务和流程的熟悉,紧张而忙碌。

一晃一月过去了,经历了几次问题,幸运的是最终都得以妥善解决。在此期间日志系统、监控系统、数据监控系统等周边系统逐步上线,一切朝着稳定的方向前进。

新的挑战

”谁的江山,马蹄声狂乱,我一身的戎装,呼啸沧桑“——《菊花台》

搬到新的办公场地,还没有装修好,一切从简。

面对着黄浦江,看着江上船来船往。

有一天,er忽然抬头笑道:你看,这江边有很多树啊

我道:嗯。 

er道:你可知道有多少棵 

我道:三十七棵。 

er的心沉落了下去,笑容也冻结。 

因为他数过江边的树。他了解一个人在数树时,那是多么寂寞。

4月25日,火理财项目正式启动,第4天后台所有接口ready,第8天,iOS版本出企业版,第10天,安卓版上线,创业的速度,创业的激情,狼性的团队,已不再是寂寞。

内测版通过,公测版通过,5月正式上线。

不曾到过的世界

“有的人求名,有的人求利,我求的是什么呢?”  -——《陆小凤传奇》

第1期,1万

第2期,50万 144小时

第3期,100万 14小时

第4期,100万 10小时

……

……

第65期,700万 12小时

到第40期,项目投资总额就已经超过了1个亿。

见或不见,一个亿就在那里,不悲不喜

念或不念,一天700万就在那里,只增不减

跟或不跟,各种问题就在那里,不增只减

这样的一个世界,光怪陆离,不曾到过,曾想过,只是没想过会来得这么快。

手机24小时开机,电脑24小时在身边,快速处理所有发生的问题,我们做的是金融,过手的都是钱,不能有个万一,兢兢业业,诚惶诚恐。

新版快速迭代,两周一个版本,每天后端都有迭代发布,新的规划正在实现,如此滚动……

后记一 关于技术

  • 当业务需要时,使用数据库的最高级别的事务机制保证数据的完整性;
  • 在数据库层面制定好数据约束,即使代码出错最终也不会影响数据;
  • 用户的操作最好在数据中体现出来,确保数据的完整性,关键性操作数据需要有日志类结构存在
  • 如果有第三方接口、服务或数据,在离这些接口、服务最近的地方我们需要有一个完整的日志,忠实于数据的出和入。
  • 初期个人分支开发,主干发布,中后期版本分支开发,主干发布,确保主干的持续可用。
  • 如果可以用人肉临时去解决,而技术要花比较大的成本或难度,那么直接用人去解决吧。
  • 在做方案时需要考虑数据的可追溯,特别是重要数据,简单一点留个操作日志,复杂一些,从数据结构上保证数据的可追溯。

后记二 关于管理

  • 不认同,但是执行
  • 我们要依次管理好人、产品(包括技术)和利润
  • 项目管理方式得看人,员工能力不足管理跟上,员工能力足够可以粗放管理
  • 打工要nice,创业要狼性,一团和气,必然低效
  • 当团队成员能力不齐,有高有低时,需要采用不同的管理方式,对于水平高的要多放手,少跟进,关注结果,对于水平不高的,要排期到天,多跟进。
  • 创业时需要考虑人力成本,以及人的投入产生比,重要的人做重要的事情,让其发挥其应有的价值,不合适的人要早点淘汰。
  • 管理者的分工是让大家更好,更流畅的协同工作,向同一个目标前进。团队成员可以个性鲜明,但是不能让大多数人迁就极个别的人。
  • 上层看问题,下层做事情
  • 管理者的工作:收集信息,决策

最后 招聘

开发经理

我们希望你是:

  • 能cover住20人+的团队的能力,不仅仅是某种技术
  • 能cover住每天上千万的资金流
  • 能够把握住项目的节奏,对项目结果负责

除了开发经理,我们还需要更多的PHP、安卓、iOS、前端、UI、Java、测试。欢迎推荐和自荐,base in 上海。

我的QQ:81894135

数据集合类系统如何架构

数据集合类系统如何架构

以下内容来源于QCon某高可用架构群聊天记录整理

如果携程网想把旅游信息展示到另一平台上 平台和他们的系统数据对接,pull好一些还是post好一些?或者说一个系统只是把好多其他商家的数据集合展示到统一的系统上,这样的系统一般如何架构?

先回答第一个问题:数据对接是pull好一些还是post好一些,这里需要根据实际业务做权衡,如果平台系统很大部分是通过聚合第三方数据再展示,那么比较推荐让第三方post数据,自己设计统一数据规则接口。这种情况,需要考虑自身服务的稳定性了,预防第三方误调用,击垮自身系统。如果只有小部分内容聚合第三方,那就pull,比较好保证自己系统稳定性,不过最终还得把所有的数据转换成自己格式,需要自己开发团队做这块工作。

相比较而言,post时效性高,数据交互少,如果系统会需要各个源的信息,最终也不会只是展示那么简单。如果使用post方案,则需要在接入,数据,读取等方面做隔离,在接入使用mq可以提高吞吐,在读的时候用Cache抗。并且在前期需要考虑好数据存储和数据的量级,因为是第三方的数据,在存储的扩展性方面要有比较好的方案。

最终落地的方案可能是:

按业务隔离,不同的业务相互不影响,拆分子系统;
使用redis和kafka保障高性能,kafka主要一方面用到日志上 一方面用到缓解数据库并发上;
使用nginx和lvs保障高可用;
在后期所有数据进hbase然后用storm做数据流处理和分析

以上这些并不需要一次性做到位,不要过早优化,只需要有一些大的原则,比如隔离,扩展等。小系统会随着业务慢慢演变,最终会变成大系统。在演变的过程中,可能会需要读写分离、业务分布式,分服务,架构就是在这样演变的路上成长起来的。

微信红包实现原理

微信红包实现原理

以下内容来源于QCon某高可用架构群聊天记录整理 背景:有某个朋友咨询微信红包的架构,在官方或非官方同学的解释和讨论中得出以下讨论内容,在此期间有多个同学发红包做现网算法测试。

抢红包过程

当有人在群里发了一个N人的红包,总金额M元,后台大概发生的事情如下:

一、发红包后台操作:

  1. 在数据库中增加一条红包记录,存储到CKV,设置过期时间;
  2. 在Cache(可能是腾讯内部kv数据库,基于内存,有落地,有内核态网络处理模块,以内核模块形式提供服务))中增加一条记录,存储抢红包的人数N

二、抢红包后台操作:

  1. 抢红包分为抢和拆,抢操作在Cache层完成,通过原子减操作进行红包数递减,到0就说明抢光了,最终实际进入后台拆操作的量不大,通过操作的分离将无效请求直接挡在Cache层外面。这里的原子减操作并不是真正意义上的原子减操作,是其Cache层提供的CAS,通过比较版本号不断尝试,存在一定程度上的冲突,冲突的用户会放行,让其进入下一步拆的操作,这也解释了为啥有用户抢到了拆开发现领完了的情况。
  2. 拆红包在数据库完成,通过数据库的事务操作累加已经领取的个数和金额,插入一条领取流水,入账为异步操作,这也解释了为啥在春节期间红包领取后在余额中看不到。拆的时候会实时计算金额,其金额为1分到剩余平均值2倍之间随机数,一个总金额为M元的红包,最大的红包为 M * 2 /N(且不会超过M),当拆了红包后会更新剩余金额和个数。财付通按20万笔每秒入账准备,实际只到8万每秒。

FAQ

  1. 既然在抢的时候有原子减了就不应该出现抢到了拆开没有的情况?
    这里的原子减并不是真正意义上的原子操作,是Cache层提供的CAS,通过比较版本号不断尝试。
  2. cache和db挂了怎么办?
    主备 +对账
  3. 有没有红包个数没了,但余额还有情况?
    没有,程序最后会有一个take all操作以及一个异步对账保障。
  4. 为什么要分离抢和拆?
    总思路是设置多层过滤网,层层筛选,层层减少流量和压力。这个设计最初是因为抢操作是业务层,拆是入账操作,一个操作太重了,而且中断率高。 从接口层面看,第一个接口纯缓存操作,搞压能力强,一个简单查询Cache挡住了绝大部分用户,做了第一道筛选,所以大部分人会看到已经抢完了的提示。
  5. 抢到红包后再发红包或者提现,这里有什么策略吗?
    大额优先入账策略
  6. 有没有从数据上证明每个红包的概率是不是均等?
    不是绝对均等,就是一个简单的拍脑袋算法。
  7. 拍脑袋算法,会不会出现两个最佳?
    会出现金额一样的,但是手气最佳只有一个,先抢到的那个最佳。
  8. 发红包人的钱会不会冻结?
    是直接实时扣掉,不是冻结。
  9. 采用实时算出金额是出于什么考虑?
    实时效率更高,预算才效率低下。预算还要占额外存储。因为红包只占一条记录而且有效期就几天,所以不需要多大空间。就算压力大时,水平扩展机器是。

大流量活动的应对

大流量活动的应对

大流量活动的特性是生命周期短,推广资源集中,突增流量多,对系统负载有较大的挑战,可能会对现有业务产生冲击。 在有大流量活动上线之前我们一定要做好提前准备,提前预估容量,做好扩容准备,做好应急预案。

容量预估

在确认为大流量的活动上线前需要对活动做容量预估,预估总用户量有多少,用户同时参与的可能峰值是多少?确认后评估系统能力是否能够支撑,如果不能,进行优化或扩容。评估系统时需要考虑系统本身以及支撑系统的服务的承载量。

控制节奏

控制节奏是指控制资源投放量的节奏,要有层次的将资源投放出去,不要一次性将所有资源全部砸出去,以渐进的方式,慢慢放量。如果一次性将几千万甚至上亿的量放出去,可能会导致整个活动的后台支撑系统超负载,从而影响整体活动效果。

关注用户行为

评估时考量用户的行为,识别用户的页面访问路径,如常规的活动只有一个页面,可以直接按用户数评估访问量。 如果活动一个用户一次体验流程可能会访问4到5个页面,而每个页面对后端的cgi至少产生3个请求(2个pv上报,1个用户参与状态查询),则如果有500万用户进入页面,则可能会对后端产生至少2000多万的cgi请求。如果还有页面定制的用户状态区分等,则会有更多的请求到应用服务器。

服务定制

针对大规模推广活动进行定制。此定制相对于常规逻辑来说,去掉与当前活动不相关的旁支逻辑。毕竟相对于整个系统来说,需要考虑的逻辑点会比较全,而如果只是一个活动的话,有些功能是不需要用到的,可以针对这些点做功能优化。可以考虑从入口处直接隔离,或增加定制开关。

业务隔离

承载活动运营的系统现已成为平台性的产品,有较多的业务依赖于此系统,特别是有一些非活动性的,如体系类、固化入口类的业务。 此时,当有大流量活动发布推广时需要考虑到活动本身不会对平台上其它产品产生影响,毕竟大流量活动其访问量级较大,在大资源推广时会占用服务较多的的资源,从而可能会影响其它产品的服务质量。

为保证系统上其它业务的高可用性,我们需要做业务隔离。此处业务隔离的原则:

  1. 代码保持一份,主干开发,保证主干的可用。
  2. 短期和长期的业务隔离,如通过域名分割,大流量短期活动业务启用新域名,直接扩容,流量到新机器。

如果一切顺利还好,但是往往事不与人愿,总会出一些你预想不到的情况,比如之前说好的节奏没有把控好,比如做的容量预估不够,比如……,这些比如都是我们在事前需要考虑的风险点,当这些风险出现时,我们需要做异常应对了。

假设现在流量一下子太大,已经到了服务器的负载极限,有许多用户直接被服务器拒绝服务,此时我们能够做些什么呢? 面对这种情况我们经常做的事情是扩容。

紧急扩容

扩容说白了就是加机器,其主要是考验系统的伸缩性,在不改变其它内容,仅通过增加或减少服务器的数量来扩大或缩小应用的服务处理能力。

由于业务的调用是链式的,一环扣一环,如当我们扩容后,能够应对这些流量冲击后,这个冲击可能就会触达到后端的server,或其它给我们提供服务的第三方服务,可能会一下子把第三方整得服务不可用,因此在紧急扩容前需要梳理我们依赖于哪些服务,大流量的请求中与这些服务相关的有哪些,大概有多少量级的请求会转发到这些服务上,他们的支撑能力有多少,整体容量预估是否够用,并且需要提前沟通。

假如因为某些特殊的原因,而无法扩容。此时为保证大部分用户的服务可用,我们可能需要选择服务降级。

服务降级

当应用访问遇到高峰时,超出了应用所能处理的最大能力时,为了保证整个应用的安全可用,需要进行降级,通过拒绝部分请求及关闭部分不重要的服务将系统负载降到一个安全的水平。

降级服务可以从功能和用户两个维度实现,功能降级需要将系统拆分成独立的若干个功能点,当遇到问题需要降级服务时,保证主功能的可用,一些旁支功能可以先关闭;用户降级需要在服务端实现某种策略的服务不可用,如直接抛弃用户请求。比较简单的实现就是各种系统开关,针对可以降级的功能点和服务使用开关, 当出现需要降级的情况的时候, 就可以在后台使用开关来降级。

服务降级前需要和产品侧沟通确认。

以上忝为某活动总结。

 

活动运营总结

背景

沉默一年,所做活动过百,所见所想,所思所虑。
活动常规化,小组年活动量1000+
人力不足,需求变更多,资源到位时间不定,

基础建设

  • 活动运营,想要快速,就需要有一个强大的运营平台的支持。
    建设:运营平台作为基础建设,需要作为重点投入,在建设过程中,强化运营支撑系统 大系统小做,不停的迭代,专门的产品跟进,与使用者沟通,将系统的开发和活动的开发交替给不同的开发,以调节和深入。另,在人力方面需要确保运营系统的投入。
  • 可扩展性:从运营支持平台的业务框架层面,在适应现有业务发展的基础上增加代码的通用性,在一定程度上保证系统的可扩展性。
  • 监控告警:运营系统的告警不能成为常态,一是可能会形成告警疲劳,从而放过真正的问题,二是告警会影响日常的工作开展,此时如果确认常态的告警是问题,则解决问题,如果是告警系统本身的问题,则优化告警系统。

代码架构

  • 前端静态页面,资源文件,活动隔离,按日期归档,CDN加速。
  • 前端公用库版本升级,不同版本间清晰隔离,不做兼容,固化业务逻辑抽象为公用组件,实现业务的可配置化开发。
  • 数据和页面分离,行为和表现分离,前端和后端分离,后端固化业务,中转接口。
  • 轻重分离,将固化的业务以更高性能的服务实现,将变化较多的业务需求以脚本类CGI实现。

团队

  • 固化业务外包,需要考虑人员的稳定性问题,这是一个矛盾点,并且外包政策需要切合公司的大的政策方向,存在风险点。
  • 新业务主力人员承担,待固化后可以给新同学或相对较新的同学实现。
  • 人员流动问题:做活动是比较重复的工作,在一般的团队,活动是给新人熟悉流程,熟悉业务的,而当做活动是常规工作,不做活动才是调节时,人才的选用育留是比较严峻的问题,留住一到两个核心人员,招聘合适的稳定的人,发展新的业务促进人员的成长。然而,人的问题往往是最根本的问题,也是最难解决的问题。人员的流动会成为一个一种常态,业务特性决定的,能减缓。
  • 新人问题:新人进来,总会踩到各种各样的坑,不管是产品还是开发,如何规避?新人手册?新人FAQ?导师审核?通过流程?不管是哪种方式,最后成长并适应下来的都是需要经过时间的洗礼。
  • 人员的分工:业务的模块化,从而引发人对这些模块的分工,人与模块对应上。比如接入新游戏,专人负责接入过程,负责接入后的文档撰写

需求管理

  • 同时以产品的维度和开发的维度组织;
  • 强跟进,变更的需求及时汇总;
  • 关注需求中提到的资源,如重构,资源单,号码包等,这往往是风险所在;

流程

  • 发布流程(活动发布过程检测,人工确认最终结果) 免测发布,版本发布,应用场景,开发自测,产品体验,外团体验
  • 后台CGI大变更灰度发布,前端大变更以大版本发布
  • 如何固化流程,如何确保上线的活动的正常可用,现在还在依赖于人工的检查和验证

以上是一年积累,有所感,有所想,无太多逻辑,且行且珍惜,只愿岁月静好。

产品驱动技术,改变的是kpi,
技术驱动产品,改变的是世界
这只是一个开发的遐想而已。
现实让我们知道疼!

PHP的压缩函数实现:gzencode、gzdeflate和gzcompress

  • gzencode 默认使用ZLIB_ENCODING_GZIP编码,使用gzip压缩格式,实际上是使用defalte 算法压缩数据,然后加上文件头和adler32校验
  • gzdeflate 默认使用ZLIB_ENCODING_RAW编码方式,使用deflate数据压缩算法,实际上是先用 LZ77 压缩,然后用霍夫曼编码压缩
  • gzcompress ;默认使用ZLIB_ENCODING_DEFLATE编码,使用zlib压缩格式,实际上是用 deflate 压缩数据,然后加上 zlib 头和 CRC 校验
  • 这三个函数的比较实质上是三种压缩方法:deflate, zlib, gzip的比较。
    从性能的维度看:deflate 好于 gzip 好于 zlib
    从文本文件默认压缩率压缩后体积的维度看:deflate 好于 zlib 好于 gzip

    这三种算法中gzip 、zlib的作者都是Jean-Loup Gailly和 Mark Adler。
    这两种算法以及图形格式png,使用的压缩算法却都是deflate算法。
    deflate算法是同时使用了LZ77算法与哈夫曼编码(Huffman Coding)的一个无损数据压缩算法。
    它最初是由Phil Katz为他的PKZIP归档工具第二版所定义的,后来定义在 RFC 1951规范中。

    deflate算法的压缩与解压的实现过程可以在压缩库zlib上找到。
    PHP的压缩实现依赖于zlib,zlib是一个提供了 deflate, zlib, gzip 压缩方法的函数库。
    我们所使用的上面三个函数,将参数中的encoding转为相同,压缩率设置相同,则其最终调用的是同一个函数,效果和性能一样。

    PHP的zlib实现是以扩展的方式存在于ext/zlib目录中。通过deflateInit2() + deflate() + deflateEnd()三个函数配合完成压缩功能,inflateInit2() + inflate() + inflateEnd()三个函数配合完成解压功能。压缩最终都是通过php_zlib_encode函数实现调用,除了输入的字符串,压缩率,结果的输出外,不同的入口函数调用参数不同的是其encoding。deflateInit2的第四个参数指定encoding,PHP定义了三个常量:

     #define PHP_ZLIB_ENCODING_RAW          -0xf      //deflate -15
    #define PHP_ZLIB_ENCODING_GZIP          0x1f      //gzip 15 + 16
    #define PHP_ZLIB_ENCODING_DEFLATE     0x0f      // zlib 15

    三个函数在调用过程可以直接指定encoding使用其它的算法:

    zlib:   ZLIB_ENCODING_DEFLATE 
    gzip: ZLIB_ENCODING_GZIP
    deflate: ZLIB_ENCODING_RAW

    此三个函数是三种算法的简单调用方式,以更好的命名展现。三个函数间可以通过指定相同的encoding达到相同的效果,并且PHP也提供zlib_encode函数作为通用的压缩函数。

    参考资料:

    http://www.gzip.org/zlib/rfc-deflate.html

PHP成员变量获取对比

有如下4个代码示例,你认为他们创建对象,并获得成员变量的速度排序是怎样的?

1:将成员变量设置为public,通过赋值操作给成员变量赋值,直接获取变量

	class Foo {
		public $id;
	}
 
	$data = new Foo;
	$data->id = 10;
	echo $data->id;

2:将成员变量设置为public,通过构造函数设置成员变量的值,直接获取变量

        class Foo2 {
		public $id;
		public function __construct($id) {
			$this->id = $id;
		}
	}
 
	$data = new Foo2(10);
	echo $data->id;

3:将成员变量设置为protected,通过构造函数设置成员变量的值,通过成员方法获取变量

 
     class Foo3 {
		protected $id;
		public function __construct($id) {
			$this->id = $id;
		}
 
		public function getId() {
			return $this->id;
		}
	}
	$data = new Foo3(10);
	echo $data->getId();

4:将成员变量设置为protected,通过构造函数设置成员变量的值,通过魔术方法获取变量

 
     class Foo4 {
		protected $id;
		public function __construct($id) {
			$this->id = $id;
		}
 
		public function __get($key) {
			return $this->id;
		}
	}
	$data = new Foo4(10);
	echo $data->id;

按执行速度快慢排序: 1243
咱们先看其opcode:

1:

   	1  ZEND_FETCH_CLASS	4 	:4 	'Foo'
	2  NEW      			$5	:4
	3  DO_FCALL_BY_NAME			0          
	4  ASSIGN     				!0, $5
	5  ZEND_ASSIGN_OBJ			!0, 'id'
	6  ZEND_OP_DATA				10
	7  FETCH_OBJ_R			$9	!0, 'id'
	8  ECHO        				$9

2:

	1  ZEND_FETCH_CLASS	4 	:10	'Foo2'
	2  NEW             		$11	:10
	3  SEND_VAL        			10
	4  DO_FCALL_BY_NAME		1 
	5  ASSIGN    				!1, $11
	6  FETCH_OBJ_R			$14	!1, 'id'
	7  ECHO        				$14

3:

	1  ZEND_FETCH_CLASS	4 	:15	'Foo3'
	2  NEW         			$16	:15
	3  SEND_VAL     			10
	4  DO_FCALL_BY_NAME			1          
	5  ASSIGN  	   			!2, $16
	6  ZEND_INIT_METHOD_CALL	!2, 'getId'
	7  DO_FCALL_BY_NAME		0 	$20     
	8  ECHO       				$20

4:

	1  ZEND_FETCH_CLASS	4  :21	'Foo4'
	2  NEW          		$22	:21
	3  END_VAL      			10
	4  DO_FCALL_BY_NAME		1          
	5  ASSIGN        			!3, $22
	6  FETCH_OBJ_R  		$25 !3, 'id'
	7   ECHO  				$25

根据上面的opcode,参照其在zend_vm_execute.h文件对应的opcode实现,我们可以发现什么?

一、PHP内核创建对象的过程分为三步:

  1. ZEND_FETCH_CLASS 根据类名获取存储类的变量,其实现为一个hashtalbe EG(class_table) 的查找操作
  2. NEW 初始化对象,将EX(call)->fbc指向构造函数指针。
  3. 调用构造函数,其调用和其它的函数调用是一样,都是调用zend_do_fcall_common_helper_SPEC

二、魔术方法的调用是通过条件触发的,并不是直接调用,如我们示例中的成员变量id的获取(zend_std_read_property),其步骤为:

  1. 获取对象的属性,如果存在,转第二步;如果没有相关属性,转第三步
  2. 从对象的properties查找是否存在与名称对应的属性存在,如果存在返回结果,如果不存在,转第三步
  3. 如果存在__get魔术方法,则调用此方法获取变量,如果不存在,报错

回到排序的问题:

一、第一个和第二个的区别是什么?

第二个的opcode比第一个要少,反而比第一个要慢一些,因为构造函数多了参数,多了一个参数处理的opcode。参数处理是一个比较费时的操作,当我们在做代码优化时,一些不必要的参数能去掉就去掉;当一个函数有多个参数时,可以考虑通过一个数组将其封装后传递进来。

二、为啥第三个最慢?

因为其获取参数其本质上是一次对象成员方法的调用,方法的调用成本高于变量的获取

三、为啥第四个比第三个要快?

因为第四个的操作实质上获取变量,只不过其内部实现了魔术方法的调用,相对于用户定义的方法,内部函数的调用的效率会高。因此,当我们有一些PHP内核实现的方法可以调用时就不要重复发明轮子了。

四、为啥第四个比第二个要慢?

因为在PHP的对象获取变量的过程中,当成员变量在类的定义不在在时,会去调用PHP特有的魔术方法__get,多了一次魔术方法的调用。

总结一下:

  1. 使用PHP内置函数
  2. 并不是事必面向对象(OOP),面向对象往往开销很大,每个方法和对象调用都会消耗很多内存。
  3. 尽量少用魔术方法 — 除非有必要,不要用框架,因为框架都有大量的魔术方法使用。
  4. 在性能优先的应用场景中,将成员变量设置为public,不失为一种比较好的方法,当你需要用到OOP时。
  5. 能使用PHP语法结构的不要用函数,能使用内置函数的不要自己写,能用函数的不要用对象

2013年的多与少

多,甲骨文字形,从二“夕”。“夕”本义指“黄昏时刻”,转义指“黄昏时刻农夫聚集”。“二夕”叠加指“农夫加倍聚集”。表示数量大,与“少”、“寡”相对。
少,小篆从小,本义:不多。

2014年的第一天,带着包包大人,和家人一起爬山,登高而没有望远。
睡醒,起床,开始这篇该有的年度总结。

跨过一年,表示我离不二的年纪不远了,呵,回首一年,生活因包包大人的到来而发生了彻底的改变,技术没有明显的进步,进了想去的公司。
一年,有得有失,在选择中成长;
一年,有累有喜,在成长中成熟;
一年,有多有少,在变化中变化。

一、2013年的多与少

多了什么?
多了一个小天使
多了一份责任
多了一个完完整整的家,有你们的地方就是家
多了并不是多余,只是增加。

少了什么?
少了二人世界,世界将围绕小天使转
少了看书的时间
少了周末的爬山和运动
少了并不是真少了,只是转移,有更多需要你来兼顾。

多了什么?
多了能够见识的东西,更多的同事,更多的学习资料、更多的组件,更多的之前都没有见过的东西。
多了需要面对的用户,海量的用户,一个小小的手抖可能就是一大堆的投诉
多了需要考量的因素,所处的环境更复杂

少了什么?
少了责任,不再需要考虑他人的成长,关注更具体的事情。
少了思考,思考个人的成长?思考自己的价值,思考过去所做的事情,思考将来要做的?这些少了。慢慢就少了,无声无息的。
不在那个位置,你就不会去思考那个位置的问题,所谓 在其位谋其政,在其位的驱动力没有了,是否还能自动的去思考?
少了沉淀 一方面博客没有及时更新了,一方面看书的时间也减少了,每天围绕着需求在变。

一些个人感觉:
重回一线,开始了重新写代码的日子。
站的位置不同,看到的东西也不同,开发是最了解实现的人,也应该是最能发现bug的人,只是我们懒了,
如何去做?自测,严格的自测,除了正常流,遍历代码中所有的异常流,只是能有几人可以做到,因为我们都相信我们的代码是没有问题的。

更深刻的体会了业务决定实现,也决定了你对一个技术使用熟练程度。不经历一线的考验的技术不可能到一个很熟练的程度。

最重要的是什么?我们知道事分轻重缓急,重要紧急的事先做,只是往往我们认不清自己在做的是不是最重要的。
一个时间点上,你最重要的是什么?
一件事中,你最重要的是什么?
一些人里,你最重要的是谁?

2013年是一个变化年,生活状态的变化,因为变化,对比上一篇总结的计划:
1、过PMP【完成】
2、看5+管理 10+技术 10+其它书籍 【完成】只是效果不是太好,特别是临近这两三个月。
3、熟悉YII框架的源代码,对其各个模块有清晰的认识(貌似这里没量化了)【基本完成】最近在工作中也用得比较多
4、加强对Linux的认识(量化一些,虐APUE两遍,并结合PHP内核)【未完成】
5、完成媳妇的两个梦想【完成】
6、加强在工作上的掌控力,项目的按时完成率在80%以上。【需求变化】
7、Blog – 平均每月两篇+,【没有完成】博客没有及时更新,这就不找借口了,主要原因是个人没有积累,也没有去关注了。

二、2014年计划

1、博客 两周一篇 是为了沉淀,也是为了让自己思考,给自己留下思考的时间;
2、读书 与上面相关,虽然这是一种投入产出比不高的活动,但其精髓在于慢,数量为40;
3、技术 需要对linux有更深入的了解,APUE,linux内核,操作系统,系统架构;
4、运动 每两周至少大活动量的运动一次。
5、包包大人健康的长大
6、老婆大人的新年愿望

三、感恩

感谢老婆大人,是你辛苦将我们的宝贝包包大人带到这个世界,辛苦了!!
感谢两边的父母亲,你们养育了我们,为我们操碎了心,小宝宝出来了,你们还得操心,谢谢!
感谢在WS的朋友和同事,虽然离开了,但是你们曾经对我的帮助铭刻在心。
感谢兄弟的一路相随!
感谢er、reeze、张老板,terry,blank,感谢这一年在我生命中出现的人们,感恩。

四、结束语

2013还可回首望望,只是已经过去,现在还在我们手里,把握现在的你手里的,你身边的,相信未来会更美好。
2013~2014,很好的年份,1314,希望没有找到另一半早点成家,成了家的早点有小宝宝,一生一世。

五、附录A 2013读书列表

《你的灯亮着吗?》读书笔记

1、当遇到一个问题时,先不要急着去解决问题,而是问下自己 问题是什么?为谁解决问题?谁有问题? 确切的说是需要寻找问题的本质,更全面的考虑问题
2、问题其实是人期望的东西和你体验的东西之间的差别,简单点说与预期不符。
3、不要过早的下结论,但是也不要忽略你的第一印象
4、当解决一个问题的时候,可能会带来一个新的问题,从而子子孙孙无穷尽也。
5、问题最难处理的却是意识到问题的存在,这里的关键是思考,思考之后才会能发现问题。
6、一旦我们把一个东西当作一个问题,我们通常会给它“变形”
7、当你在寻找问题定义的道路上疲倦地游荡时,不要忘记随时都回头看看,看看你是不是已经迷路了。
8、注意你说话的上下文,有些信息是你知道,而别人不知道的,所以,当说一件事情的时候需要确保信息对等,如果信息不对等,请在你的表述中将这些信息带上。
9、一旦你用文字表述一个问题,请仔细推敲这些文字,以使这种表述在每个人的头脑中都是同一个意思。
10、当别人能够很好地解决自己的问题的时候,千万不要越俎代庖。这时不是看问题了,而是解决问题,一线的问题让一线的人解决吧。
11、如果某人能够解决这个问题,但是他本人却并不会遇到这一问题时,那么你们首先要做的就是让他也感受到这个问题。
12、当指责别人没有解决问题时,试试换过来指责你自己-即使只有一秒钟。
13、你的灯亮着吗?
14、问题的根源常常在你自己身上。
15、问题从哪儿来?找到问题的根源。
16、在这个世界上有两种人,一种人做事,另一处人给别人找事做。这个世界上也可能有另外两种人,一种人做事,一种人享受荣誉。
17、看看我们现在处理的难题,那些你看起来不可能解决的问题只需要再多花一点时间就能解决。当你解决了这个问题时,回过头来看看,觉得也许没有想象中的那么困难,行百里者半于九十
18、追求什么,就能够学到什么
19、不管看上去如何,人们很少知道他们想要什么,直到你给了他们想要的东西。
20、最终的分析表明,并没有多少人真的希望他们的问题被解决。
21、开始之前,想想我是否真的想要一个解决方法?
22、解决问题不要太快,快往往代表着仓促,仓促往往会容易出错。
23、过去的已经过去,现在的还在现在,将来的永远是将来。忘掉过去,把握现在,相信将来!
24、首先,对自己要真诚。对自己要真诚,在这里的意思是,在你靠近一个解决方案、甚至一个定义之前,你必须考虑道德的问题,然后再开始降低你的敏感度。这种考虑永远都不会是浪费你的时间,因为解决问题永远都不会是一个道德上中立的行为――不管它是多么的吸引它的从业者们。

开发过程中的偏误

开发的一生应当这样度过:当他回首往事的时候,不会因为没有时间陪妹子而悔恨,也不会因为没有浏览过祖国的大好河山而愧疚。这样,在临终的时候,他就能够说:‘我已把自己整个的生命和全部的精力献给了世界上最壮丽的事业——编程。

作为一个开发人员,每天吭吭哧哧的编码,调试,面对产品MM的需求变更,应对测试MM的各种挑战,呼啦啦,需求上线了,看数据,有告警,马上处理,没有告警,安心做下一个需求,眼睛一睁一闭,一天就过去了,要是一闭不睁呢?

在无比享受的开发过程中,我们可能会存在一些偏误,你见或不见,它就在那里,不增不减,不悲不喜。

在开发的世界中,总会有一种老子天下第一的气势,所谓文无第一,武无第二,开发也是。当一个需求开发完成后,我们都会认为我们的代码是很完美的,它能很好的实现产品的需求,没有bug,当测试MM说开发哥,你这里是不是有bug?第一反应是:怎么可能?是不是环境有问题。这是属于开发的过度自信偏误,但这并不是开发独有的,我们大多数人都有这个问题,只是强弱程度不一样。过度自信偏误对专家的影响比对非专家的影响要大,男人比女人更大,作为以男性居多的开发领域的专家,这个问题比较突出就不奇怪了。

建议:我们需要基于现场的实际情况做出自己的判断。

隔壁组开始用Go写他们的业务了,NB大发了,要不我们也试试?昨天那个分享中有介绍node.js,现在用的人蛮多的,咱们是不是也用一下试试?现在业内流行特定领域语言,咱们也是不是开发一套……

为什么我们会对大家都在使用的一些东西比较关注?为什么?从众心理。剧场中,当表演到精彩处,有一个人带头鼓起掌来,于是整个剧场都将掌声雷动;喜剧节目或访谈节目时,在关键位置插入笑声往往会引发观众的笑声。如果只是你一个人,也许就没有这样的效果了。
技术人员对技术有着特殊的激情,当一堆人开始讨论某些技术的时候,如果自己不知道一些总会觉得不太和谐,于是开始研究,应用,甚至为这种技术布道。

建议:对于热门的技术和大家都在谈论的技术,了解可以,具体应用到业务,需要做详细的评估,确认此种技术出现的应用场景,以及是否适用我们当前的业务,一种技术的引进有时是种进步,有时会成为技术负债。

系统告警,组内的人都收到了短信,可这是一个公共模块,谁去处理呢?你想,嗯,总会有人去处理的,于是等啊等啊,终于,一堆的客户投诉到了客服那里,事故升级,大家都挨批了。什么原因?三个和尚没水喝的故事再次重演了呗。如同一堆人一起拉绳子,人越多,个人的贡献越低。这被称之为社会性懈怠,在团队里不仅我们的效率会被克制,我们的责任也会被克制,如同刚才告警的例子,谁也不想为之负责。但这是一种理由性行为:假如使出半力就行,又不会引起注意,为什么要使出全力呢?

建议:团队业务模块化,责任到人,通过彰显个人效率来缓和这种懈怠。

以上只是我们常遇到的一小部分偏误,不仅仅是我们开发,大部分人也有同样的问题,偏误很多,只是你有没有清醒的认识到?

奇志大兵的相声中有这样一句词:偏爱,偏爱离正爱就不远了吧

偏误也是!