谈谈微信的信息流

最近才更新到微信的最新版本,早有耳闻公众号变成了微博似的信息流展示信息。之前也没有太在意,这次微信客户端版本更新以后,发现坏了坏了,以往的阅读习惯已经被彻底毁掉了。下面两图都是我手机上的截图,左边是新的信息流模式,右边是信息流界面下点击右上角图标,回到的“类似以往”的基于订阅号发布者的模式。

image1 image2

首先我要澄清的是,我认为信息流是绝大多数 SNS 软件都乐意采用的信息传递模式,简洁而且高效,包括我经常使用的那些应用,比如微博,比如知乎,比如 LinkedIn,甚至绝大多数 RSS 软件,因此,它绝不是一个新东西。毫无疑问,基于信息和基于信息发布账号(公众号)的方式比较起来,通常前者更有优势,但是此事

[……]阅读全文

招聘有多重要?

A red vintage “for hire” sign招聘有多重要?

很重要……

嗯,废话!

说“很重要”的确是废话,而没有比较就没有差异,同样一句“很重要”我看到许多人理解其程度实际上大相径庭。在很多互联网公司,招聘被视为“最重要”的事情。这是令许多人不理解,甚至觉得不可思议的事情,这里的“许多人”也包括曾经的我。公司不开展业务吗?不管理员工吗?不和了解客户需求吗?这些事情哪个不比招聘重要呢?

中午吃饭的时候,同事老兔和我算了这么一笔账。估算非常之粗略,请勿以之作为任何有效依据,但是从大略上足以窥其端倪。

  1. 假如一个勤奋的中级程序员工程师,一年薪水 200K 的话,一年 365 天,大约有 52 周,扣掉双休日还有 365-52*2 = 261 天,加上法定假大概 10 天,

[……]阅读全文

独立游戏推荐

如今各种平台上的大作满天飞,可是不知道有多少人和我一样,很难对这些大作燃起热情。可是凭着怀旧的心态,去回味一下老游戏,或者所谓的“经典”的时候,却又发现时过境迁,物是人非,一样缺少玩下去的动力。平时工作生活就很忙了,留下属于自己的时间不太多,也不太愿意沉迷太多的时间给或新或老的游戏,再加上随着年龄的增长,似乎对越来越多的事情失去了兴趣。直到某些“独立游戏”出现,由于资金、人力的关系,它们大多没有绚烂的画面,繁冗的剧情,以及漫长的游戏时间,但是由于开发者可以决定它们的走向,始终围绕核心想法构建,于是它们或精致或别样,总能把某一游戏性发挥到极致,让我重新找到许多游戏的快乐。我不算什么资深玩家,在这 [……] 阅读全文

评审的艺术——谈谈现实中的代码评审

曾经写过一点关于代码评审(code review)的文章,比如 这篇这篇 ,现在觉得关于它的认识又有了不少更新。软件工程的技术和实践分成两部分,一部分是和书本知识一致的,大约占一半,这部分基本上在大学里就可以学,自学只要方法得当、刻苦努力也可是途径;但是第二部分来自于实际团队、经验,内容通常无法从书本当中获得,而且难说对错,不同的人和不同的经历造就了不同的认识。代码评审就是第二部分颇具槽点,可以大加讨论的典型。

代码评审是展现个性和性格的途径

我本人特别反对一种颇为常见的观点,就是“一个良好运作的项目,不同的人,应该写出一样的代码”。我非常理解这种观点的初衷,一个良好规范约束的团队中 [……] 阅读全文

折腾的快乐

sde

先讲个故事

公司里有这么一个小小的差事,某一个月,每天都要把 Excel 的某一列的数据根据某种规则换算以后拷贝到另一列去。

DA(数据分析师)看了以后说,就手工完成吧。反正只有一个月,这件事情每天做 3 分钟,也没有多耽误时间。

TPM 看了以后说,这事情每天做做很简单啊,写一张便签贴在屏幕上,每天就不会忘记了。

Dev Manager 看了以后说,衡量一下这个很小的时间成本,用其它的方式来解决是不划算的,还是手工搞定吧。

……

不过地球上还有一种特殊的物种不同意。它门叫做程序员——这么重复性的劳动难道不能用脚本完成吗?

就是,用 geek 的脚趾头想一想,这还用问?

于是写脚本,调试,测试,整合,两个钟

[……]阅读全文

求第 K 个数的问题

一道经典的题目。给一堆乱序的数,如果它们从小到大排好,求第 k 个是多少。假设排列的下标从 1 开始,而非 0 开始。

这个问题如此之简单而熟悉,可它却可以是很多现实问题的某一个子问题的抽象。它本身相关的问题其实就不少,而且还可以不断演进,成为不同复杂程度的问题。

看到这个问题,脑海里的第一反应是一左一右红蓝两条分支——堆排序或者快排。Java 中快排用 Arrays.sort 就可以了,如果是堆排序需要用到 PriorityQueue。 用 Arrays.sort 写起来最简单(这里的参数校验都省掉了):

public int getKth(int[] nums, int k) {
    int[

[……]阅读全文

一些前端框架的比较(下)——Ember.js 和 React

JavaScript framworks

这是前端框架比较和吐槽的第二篇。

Ember.js

Ember.js 的 extend 的写法很类似于 JQuery 或者是 Backbone.js,创建 Application,然后在它下面创建相应的 Model(Object)、Controller、Router、View 和 Template,这些都是非常类似的。但是它更为先进的地方在于,一些重复的样板代码,比如给 template 注入上下文并渲染,如果命名按照 CoC 的原则正确完成的话,都由框架自动完成,这就省去不少体力活 。CoC 还体现在 URL mapping 上面,比如”/books/book_id” 配置在 books.index 的 Router 里,Contro

[……]阅读全文

一些前端框架的比较(上)——GWT、AngularJS 和 Backbone.js

JavaScript framworks

和一些前端框架打过交道,想起来这也是技术选型中经常面对的内容。我把我的经验、思考、感受,甚至是吐槽,记录在这里,有些零散,并且更多的是个人的感悟。而且由于技术所限,可能部分内容不够深入,或者不甚客观。当然,网上有很多分析对比,视角可能更为全面和系统。如果你在技术选型,或者在考虑要学习使用哪一款 MVC/MVP/MVVM 框架的时候,此文能够给你有价值的信息,就更棒了。如果你觉得我哪些部分说得不正确,或者需要补充,也烦请告知。

需要预先说明的是,这篇文章不是教程,因此如果你对其中某一框架知之甚少,可能需要先去简单学习了解以后才能和我产生共鸣,或者产生反驳的冲动。

以下是第一部分,先谈谈 GWT、An

[……]阅读全文

工作流系统的设计

workflow

几年前曾经写过一点点对于 缓存框架设计 的体会,这大半年和工作流系统打交道颇为丰富,因此想总结一点关于工作流系统的设计。

首先,明确工作流(workflow)系统的定义。 维基百科 上有极其简单的介绍。我记得以前在文章里面说过,作为大公司里面的小 team,为了做一些有趣的东西,从而更好的招人,通常有几个众人皆知的突破口:比如一个更符合业务需求的 storage,再比如一个自定义的工作流系统。在 Amazon 内部,我接触过好多个 workflow,而且大多以 Amazon SWF 为原型(当时学习的时候还写了一点体会,link 1link 2),于是宏观上看,60% 的东西是一样的,大同小异;但是也有很多重

[……]阅读全文

从淘汰 Oracle 数据库的事情说起

tech

公司搞淘汰 Oracle 数据库的事情已经搞了好久了,这个事情其实和国内淘宝系搞的去 IOE(IBM、Oracle 和 EMC)是类似的,基本上也是迫不得已,Oracle 的维护成本太高,而公司内部基于 Oracle 数据库的数据仓库,也是问题频出;另一个原因则是 scalability。我相信这两个原因许多人都非常清楚。而这个淘汰,也不是简简单单换一个关系数据库,比如把 Oracle 换成 MySQL,或者换到云上(RDS)。而是有明确阶段性地演进,比如替换到 DynamoDB 这样的 NoSQL 数据库上面去;或者更彻底地,像我们接触到的某个产品,数据本身换到更廉价的存储 S3 上去,元数据才存在 DynamoDB 里,而原本

[……]阅读全文

Spark 的性能调优

Spark

下面这些关于 Spark 的性能调优项,有的是来自官方的,有的是来自别的的工程师,有的则是我自己总结的。

基本概念和原则

首先,要搞清楚 Spark 的几个基本概念和原则,否则系统的性能调优无从谈起:

  • 每一台 host 上面可以并行 N 个 worker,每一个 worker 下面可以并行 M 个 executor,task 们会被分配到 executor 上面去执行。Stage 指的是一组并行运行的 task,stage 内部是不能出现 shuffle 的,因为 shuffle 的就像篱笆一样阻止了并行 task 的运行,遇到 shuffle 就意味着到了 stage 的边界。
  • CPU 的 core 数量,每个 executor 可以占用一个或多个 core

[……]阅读全文

“残酷”的事实

crazy

下面这些文字来自我在知乎的回答:“在真实工作中的编程是怎么样的,与学校里有什么不同?”

入行愉快。

首先,一言以蔽之,用两个字来概括,就是“残酷”,但是,好在是加引号的。有的不但残酷,还很无奈;有的则是在残酷的同时,还很有趣。搞工程和学校里的象牙塔大不相同,这也许老早就知道,但是绝对不是七八年前我想象的模样。你可以把它当成我没睡醒的呓语,也可以当成我喝多的胡话,或者是心情太差的时候写的吐槽檄文。反正,它们就在那里,事实就在那里。

总的来说,学校里面编程,或者在工作之余编程,是很有趣的,没有 manager 给你各种压力,也没有各种大神(比如 TMP、PM、SE 等等我都搞不清楚干嘛的职位)给你指点

[……]阅读全文

七年工作,几个故事

journey

从毕业工作到现在,已经有七个年头,年头虽然不久,但是回过头来看看那些经历的好的坏的有趣的扯淡的事情,还是有很多东西可以总结。所有人都会或多或少走弯路,本来成长就是这样一个过程,有时候想起来会感叹,有时候会唏嘘,有时候会一笑而过。我的前一半时间是在华为,这段时间留给我很多回忆(比如 这几个瞬间);后半时间在亚马逊,也给了我不少感慨的机会。下面这些故事都是我经历的真真实实的事,有的事情已经过去好久,但我不想把它永远尘封。也许你和我在某些方面,会有共同的体会。

在我说这些故事前,或者说,吐这些槽前,我想说这样三个观点。

首先,为自己工作。

不是为父母,不是为同事,不是为公司,[……] 阅读全文

从 Java 和 JavaScript 来学习 Haskell 和 Groovy(汇总)

programming language

这是这个系列的最后一篇,从编程范型的角度概览,前面几篇的链接在文章后半部分有汇总。

我在之前已经 介绍过编程范型的概念 ,而事实上,我们到现在为止,纠结在这四门迥异的语言上面,浅看是各种语言特性,深看就是编程范型和思维方法。

下面这张“神图”来自于 这里 ,可以说是对于范型和语言归类的概览,从左往右从更强的声明式向着更弱的声明式发展;依据状态分为 Unnamed state(串行或并发,包含逻辑式和函数式这几种分类)、Nondet. state(所谓的不确定性状态)和 Named state(包含数据流、消息传递和状态共享这几种分类),Haskell 出现在了左侧函数式语言的分支内,而 Java 出现在了右侧

[……]阅读全文

系统设计典型问题的思考

CAP 系统设计方面的问题问题是非常考验经验和思维过程的,而且和常见的算法问题、语言基础问题不同,涉及的面很广,还没有比较一致的判别标准。但无论如何,还是可以归纳一些常见的思路和典型问题的线索。

首先,反复沟通和澄清系统需求。只有把需求澄清清楚了,才可以开始思考并落到纸面上。但是需求的沟通应该是持续和循序渐进的,问题很难从一开始就思考全面。最重要的条目包括:

  • use cases,通常问题只需要 2~3 个 use cases 需要考虑,其他的部分会晚些考虑,或者不考虑。这样就可以简化问题。
  • 用户数量(用户可以是下游系统或者人)、数据数量,澄清这个事实无疑非常重要,对系统设计的决策有重大意义。
  • 请求模型,

[……]阅读全文

一道随机数题目的求解

random 有这样一道算法题:

给定一个能够生成均匀 1~5 随机枚举数的函数,请设计一个能够生成均匀 1~7 随机枚举数的函数。

就是说,有一个生成随机数的函数 rand5,可能返回 1、2、3、4、5 这 5 个枚举值,其中每个值被返回的概率都是严格的 1/5,现在需要设计一个类似的随机数函数 rand7,可能返回 1、2、3、4、5、6、7 这几个枚举值,每个值被返回的概率都是严格的 1/7。

先掩卷思考,脑海中浮现的思路包括:

  • 调用 rand5 的结果除以 5,再乘以 7,这样的结果范围为 7/5~7,并非所希望的结果;
  • 反复调用 rand5 函数 7 次,结果再除以 5,这样的结果范围为也为 7/5 ~ 7,并非所

[……]阅读全文

LeetCode 算法题目解答汇总

LeetCode

[Updated on 9/22/2017] 如今回头看来,里面很多做法都不是最佳的,有的从复杂度上根本就不是最优解,有的写的太啰嗦,有的则用了一些过于 tricky 的方法。我没有为了这个再更新,就让它们去吧。请读者知道这一点。

只要不是特别忙或者特别不方便,最近一直保持着每天做几道算法题的规律,到后来随着难度的增加,每天做的题目越来越少。我的初衷就是练习,因为一方面我本身算法基础并不好,再一方面是因为工作以后传统意义上所谓算法的东西接触还是太少。为了题目查找方便起见,我把之前几篇陆陆续续贴出来的我对 LeetCode 上面算法题的解答汇总在下面,CTRL+F 就可以比较方便地找到。由于 [……] 阅读全文

层次

level

以下文字,看看就好,笑笑就好。

最近在被一个问题折磨,大致上是,公司内部某些技术更替的关系,要把原有的一个鉴权的组件 A 淘汰掉,迁移到一个新的替代品 B 上,我估摸着也就一天时间搞定它绰绰有余了。没料想一猛子扎进去就没那么容易出来了,替换完成以后的测试傻了眼,发现了一个诡异的问题,于是追根溯源,把牵涉进来的林林总总一一拖出来检查排除枪毙,环境比较复杂,debug 起来又比较头疼,折磨了三天半的时间;最后还靠这个替代品 B 的问题列表里面,有某下游产品的工程师跳出来说是这个替代品自身有问题,分析代码怀疑是如何如何的一个 bug,于是我也按照这个思路修改它的代码,编译并且打上补丁以后,才发现确实修复了我遇

[……]阅读全文

Dynamo 的实现技术和去中心化

Amazon Dynamo 是分布式的 key-value 系统,最近阅读了 Dynamo 最初的论文 《Dynamo: Amazon's Highly Available Key-value Store》,本文想聊一聊它的去中心化(decentralization)。既有阅读相关材料后对其实现的理解,也有自己的思考,其中如有不正确言论欢迎指出。

中心节点

通常,我们见到的分布式存储结构都是具备中心(总控)节点的,比如 Google File System(GFS),包括了中心的 Master 和数据节点 Chunck Server;再比如 HDFS,包括了中心的 Name Node 和数据节点 Data

[……]阅读全文

也谈谈全栈工程师

thinking

纵使目标再大,人的精力有限,于我来说,早些时候远大目标隐约是“成功的软件工程师”这个样子,但是目标是需要逐渐细化的。这些年我渐渐对自己的定位和未来有了一个清晰一点的认识。确实我有很强的观点,觉得软件工程师需要有足够的全面性,在 《我眼中的工程师文化》 中我也说“工程师文化,不是只有权力的一面,它对工程师的要求,是每个人都要足够能干,都要做许多的事”……

但是,全面性不代表没有专精、没有方向。深度和广度统一的问题已经有许许多多过往的人和我说过了,不存在一个在某一领域精深的牛人但是知识却很窄,也不存在一个博学大师但是却没有一个自己擅长的领域;而方向更是不可回避的问题,以前和朋友开玩笑总结了几类工程师

[……]阅读全文

back to top