使用Kubeadm 1.6部署Kubernetes

本文介绍了如何用Kubeadm 1.6版在Ubuntu 16.04系统上快速部署一个Kubernetes集群。 环境 阿里云ECS 华南1 可用区A Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-63-generic x86_64) 专有网络 节点类型 配置 内网IP MASTER 1 CPU 1GB RAM 172.18.214.46 Node 1 CPU 2GB RAM 172.18.214.47 依赖安装&&代理设置 首先要在两个节点都安装Docker和Kubernetes相关的组件。因为相关的镜像都在墙外,所以这里需要挂代理或者自行寻找墙内的源。笔者选择的是挂代理的方案,给Ubuntu配置HTTP代理可以参考这篇博客。给Docker配置代理可以参考官方文档 安装的步骤是按照官网的文档Installing Kubernetes on Linux with kubeadm来的: # 升级包管理的镜像列表 apt-get update && apt-get install -y apt-transport-https # 将docker和kubernetes相关的镜像源加入列表 curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - cat <<EOF >/etc/apt/sources.list.d/kubernetes.list deb http://apt.kubernetes.io/ kubernetes-xenial main EOF apt-get update # 安装docker和kubernetes相关组件 apt-get install -y docker-engine apt-get install -y kubelet kubeadm kubectl kubernetes-cni 初始化 在MASTER节点运行:...

May 24, 2017

基于Travis CI和Github的前端云构建

最近在思考团队里前端代码部署的问题,之前采用的方案是在本地构建,推到Github上一个专门放build后前端代码的仓库,然后Github的Webhook去触发后端的部署逻辑。代码就从这个仓库里拉取。 这种方案看起来没什么大问题,但总觉得比较awkward。首先这套方案不够自动化,需要大量的人工操作。然后Github的Webhook其实并不是特别好用,如果后期要和我们内部的私有云平台对接起来,还要经过一些桥接才可以。 本来呢,因为最近学了docker的缘故,我想写一个简单的Node服务,用来自动构建代码,然后通知服务端部署。每个应用就是一个单独的容器,这样环境就可以隔离。这个方案想来也不错。直到我仔细研究了一下Travis CI,才发现这个CI真是不简单。云端构建的任务用Travis CI就可以完美的实现。 关于CI CI是持续集成的意思,持续集成里主要包括构建和测试代码。之前对Travis CI的印象是可以跑测试,仔细看了之后才发现Travis CI其实是一个云服务,提供了一个虚拟的Linux环境。你可以运行自定义的脚本。这个Linux环境的自由度还是非常大的。对于前端构建来说,Travis CI的网络环境可以快速安装npm包,这是一个非常大的优势。 .travis.yml文件 Travis CI的配置文件其实就是让你写几个生命周期hook,内容一般是shell命令。比如install这个hook里主要写一些安装依赖的逻辑,script这个hook里主要是写测试和构建的逻辑,deploy这个hook里是写部署的逻辑。另外这几个hook都有各自的before和after版本。总而言之自由度是很大的。 一个示例.travis.yml文件。虽然我们不能直接.travis.yml中写逻辑,但我们可以运行任意的脚本,所以可以看出.travis.yml的能力基本等价于shell脚本。 language: node_js node_js: - "7" install: - npm install script: - npm run build after_script: - tar -cvf bundle.tar ./dist - node deploy.js 云端构建 在看过了上节的.travis.yml文件之后,云端构建的大致逻辑应该已经非常清楚了。我们在Travis CI的虚拟机中安装node依赖,build代码,压缩代码,然后运行一个js脚本。这个脚本的内容就是将代码上传到CDN。 deploy.js中还可以向后端的平台发送部署的请求,以达到自动部署的目的。如果后端是分布式的架构,向管理的节点发送请求即可。 一些展望 Travis CI的能力取决于这个虚拟机里提供了怎样的环境。Travis CI支持docker,因此我们可以用Travis CI进行docker镜像的构建和上传。Travis CI支持Nodejs,因此我们可以在虚拟机中安装hexo,进行博客的云端构建和自动部署。云端的构建,由于保证环境的隔离,因此稳定性会比本地高。以上都是Travis CI可能的用途。Travis CI作为一个云服务,在运维方面,还有无限的可能性等我们去探索

May 22, 2017

《编程语言实现模式》- 阅读笔记

这里记录一下我阅读《编程语言实现模式》这本书的一些感受。一开始,对于编译原理,我的印象是这门课非常的艰深。在正式学习之前其实我已经看了很多编译相关的东西,比如V8,以及前端模板引擎等等。当时的感觉就是十分神奇。上了课之后首先接触的是形式文法、自动机和正规表达式等等。我的感觉就是,这些东西,是如何被前端大神们运用来写相关框架的呢,完全看不出门路嘛! Jame Kyle的分享—《How to write a compiler》虽然很好,但是和有实际运用价值的编译技能还差的远呢。 看龙书看的欲哭无泪,后来转而看《自制编程语言》,把crowbar的代码和流程大概了解了一下。最大的收获就是了解了yacc和lex。此前我对于Lexer和Parser还是抱有一定的恐惧心理的。 最终让我认清门路的是戴嘉华的这篇博客。后来我去翻了翻编译原理课本,让我彻底搞清楚几个事情: 第一点,虽然波神说的很对,最关键的是动手去写,但了解必要的理论是很重要的。问题就在于,编译这边理论很多,类似有限自动机和正规表达式的转换等等知识,后端代码生成和优化等等,会加重认知的负担。所以关键就是,对于一个普通的工程师来说,开发文本处理或者DSL相关程序需要掌握的编译原理知识是哪些。 第二点,需要了解的概念有: 主流编译器,解释器的流水线 形式文法(EBNF) LL(1)文法,以及EBNF和LL(1)之间的转换 根据LL(1)文法写递归下降Parser 了解不同的AST类型,会设计AST 第二章&&第三章 这章主要讲基于LL(1)的Tokenizing和Parsing。 很妙的一点在于,在写关于形式文法的地方,这本书没有将BNF和乔姆斯基之类的科班教材中讲的,而是讲文法当成是一种DSL,这其实是非常正确的。Parser Generator的输入一般就是某种类似BNF的DSL。本书中的例子是ANTLR(一个parser generator)的DSL。 这种务实的风格是延续在整个第二章中的,讲LL(1)的First和Follow集的时候,是这样说的: 正规的定义中通常使用FIRST和FOLLOW两个运算来计算向前看集合,而实际使用时,这个问题可以等价于“哪些词法单元可能会出现在这个解析选项的开头”,这种思维方式更容易掌握,FIRST和严格定义就不在这里解释了,因为它比较复杂,而且这里也用不着其原理。如果有兴趣,可以在网上找到很多相关材料。 First集合的数学定义是这样的: 试想一下,如果初学者接触到的是严谨的数学定义,而不是一个相对直白的解释和代码演示的话,还是会有不少人打退堂鼓的。 在实际的学习中,还是需要一些如上文中的“等价于”那样的解释。 LL(1)的parser是最简单的。也是其余递归下降模式的基础框架。实现的方式就是为每一个规则写一个对应的函数,函数里按First集合来编写,规则里的运算符都可以转化为if或者while等到逻辑,如果是终结符就match,如果是非终结符就递归调用对应规则的函数。 我看了Regularjs中parser的代码以及上文中vdom模板引擎的代码,结合书中的例子,大概搞懂了,接下来可以把书中的例子用js写一遍试试。 第二章最后讲了LL(k)类型的parser。LL(k)就是任意k个token的lookup。LL(k)的需求,拿mcss来说,就是: mcss有点特殊,是个LL(n)的解释器,比如在设计中,函数在mcss是 First-class的,可以被返回或传入函数,并保持作用域信息,所以它是一种特殊的值,定义我设计与一般赋值一样。 $size = ($width, $height) { // … } >这里当你不读取到`{ ` 是无法判断 `=` 后面是函数定义 还是 普通css中的 compound >values . 众所周知参数列表可能无限长,所以必须是LL(n)的Parser才能够解答。 有些语言语法里有很相似的语言结构,它们只在最后边才有区别。比如C++的函数定义和函数声明的前面都是一样的,直到;或{才能加以区别。 所以想要能够写DSL解释器的话,LL(k)式的模式也是要懂的。LL(k)的问题就是要要预parse,如果条件满足,再真正parse一遍。这样带来的问题就是运行效率上比较慢。解决的办法是**回溯法**,通过类似动态规划的空间换时间的方法,缓存parse的结果,加速parse的过程。 ### 第四章 Vue的AST。

March 30, 2017

产品思维碎碎念

理论上来说,我们团队的成员都应该是对互联网有特殊热情的同学,或者是对手机里的各种App如数家珍,或者是对各大网站了如指掌。现在看来,之前有这方面的偏好,当然是好,但大多数人对互联网还没有那么深的认知。因此我觉得我们需要通过一系列的分享,来使得大家养成产品思维。 互联网公司大局 截止目前(2017年3月28日),中国上市互联网公司的市值排名前五位的是: 1 腾讯 2800亿美元 2 阿里巴巴 2668亿美元 3 百度 582亿美元 4 京东 445亿美元 5 网易 387亿美元 另外还有一些著名的上市互联网公司,比如微博、搜狐、携程等等。著名的非上市互联网公司有小米、美团和蚂蚁金服。独角兽公司(未上市,估值超过100亿美元的创业公司)有滴滴和今日头条。 这些公司基本上占据了中国互联网的大部分版图。这些公司之间由合作也有竞争,并不是毫无关系的。腾讯和阿里两个巨无霸都想在竞争对手擅长的领域布局,比如腾讯投资了京东,在腾讯的应用中,会向京东导入流量,京东的支付也会优先支持微信支付。在O2O市场,阿里投资了饿了么,腾讯投资了美团大众点评。在社交方面,阿里投资了微博,目前微博盈利能力增强,但依然和阿里有着很深的合作关系。当然阿里也进行了很多直接的收购,比如优酷和UC等。 大家要养成的能力就是,看到一家公司时,要能够说出这家公司的主流产品和所属的领域。比如阿里,大家可能觉得主要是电商,但其实阿里目前发展的比较快的还有云计算业务。了解一家公司服务的布局,最好的办法就是看公司的财报。比如大家如果看了网易的财报,就会很轻松的发现网易其实是一家游戏公司,发展的比较快的是跨境电商业务,其他就是广告收入,而其他的众多产品,在营收上贡献不大。公司毕竟是以盈利为目的的,因此盈利多的领域基本就可以认为是公司会主力经营的业务。后面我们会专门做一个《如何解读互联网公司财报》的分享。 对国外的互联网公司也要了解。虽然因为国内的政治环境、基础设施、用户群体等等原因,国内的互联网世界和国外有很多不同之处,但不可否认的是国内互联网创业的模式大部分还是借鉴国外的。比如Uber和滴滴,Twitter和微博等等。国外互联网公司,主要是美国,主要就是Google、Facebook、Aamazon、Linkedin几家大公司和Twitter、Uber、Airbnb等等有名的创业公司。国外的互联网,在技术、商业、设计和产品上都是领先的,为了拓展自己的视野,大家就更要关注了。 产品的分类 产品分类其实是一门玄学。因为分类的标准有很多种。你可以按产品的功能来分,那么自拍类产品应该属于摄影产品。但App Store里自拍相机类产品是分在社交这个分类下的,因为自拍产品最终产出的目的是为了在社交网络上展示。这是自拍产品的特有的属性。 所以分类这个,因人而异。大家只要在自己脑海里建立一个体系,遇到产品能顺利的归类,就可以了。 社交 主流的社交应用,包括很多类别,即时通讯类的主要就是微信和QQ,钉钉这样的办公应用也是这个类别。匿名社交的比如陌陌。 早期的博客和论坛,有很强的社交属性,也有一定的内容属性,我们可以叫社区类产品,暂且归类到社交类下。如果你用论坛但是只是默默潜水,那就偏内容属性,所以这个还要看用户的使用。 互联网发展早期的博客的论坛现在已经进化出了很多的形式,比如微博和贴吧。社交作为一种功能,现在也被广泛的集成到各种“主业”不是社交的应用中,比如天气App里面可以有一个简单的社区。 因此社交类应用是指,主要功能是社交的应用。其他应用也可以集成社交功能,从而拥有社交属性,比如支付宝,但这样没法改变一个应用的本质属性。大家在分析App的时候,要注意这一点。 电商 电商应用的特征相对来说比较鲜明,当然里面也可以分为B2B的比如阿里巴巴,B2C的比如天猫和京东,C2C的比如淘宝和闲鱼。电商领域按售卖商品的类别,也可以细分为,跨境电商(考拉海购、小红书)、美妆电商(蘑菇街、美丽说、聚美优品)、生鲜电商等等各种细分的市场。我们一般把这些App成为垂直领域应用。意思就是这类App的目标用户只是针对某一类人。 O2O O2O(Online To Offline)类的应用,其实应该是电商下的一个子类,和B2C和C2C并列。但由于这块市场这几年的增长非常快,潜力很大,因此现在我们一般单独拿出来讨论。 O2O主要涉及的是人的衣食住行以及吃喝玩乐,比如各种外卖(饿了么)、团购(美团大众点评)、出行(滴滴、Ofo)等等。将线下的生意和线上的在线支付和用户体系等等结合起来。 摄影 之前说了,自拍应用在App Store中是放在社交类别下的。不管如何,摄影类的应用在手机自带相机质量越来越好,社交应用非常普及的今天,需求是非常大的。看一下图片社交应用Instagram的情况,就可以知道图片社交是目前社交网络中最主流的一种形式。 这个市场的特点是基本没有一款应用能占据大部分份额,各家都有机会。这可能是因为用户对摄影的应用有着个性化的需求,也可能是因为大公司没有进入这一市场的缘故。国内在这方面做的大的是美图,现在已经在香港上市了。这一类的应用要发展,纯粹的工具属性是不够的,一般都需要借助社交平台之力。 这里要提一下的是最近非常火的短视频应用。短视频应用其实算是一种视频社交应用,放到社交分类下讨论也是可以的,比如秒拍,快手等等。自建社区毕竟是一种高风险的决策,秒拍和微博合作,因此秒拍会的内容会嵌入微博的Feed流,借助了社交平台的力量,给秒拍带来了曝光。关于短视频应用,我们今后也会进行专题的讨论。 效率工具 效率类应用有笔记应用、Office类应用、todo类应用、日程规划应用、日记应用,还有一些番茄钟应用,用来协助用户提高工作效率。 其他的工具类应用则是五花八门了,天气应用,记账应用等等,这些在App Store里面是有专门的类别的。 Workflow和Pin这种比较高端的效率App,一般都是由个人开发者开发,可以说是应用商店中的一股清流。这样的App也许是比较适合我们去尝试开发的。 旅行 旅行这个分类主要是从市场来看的,旅行类应用瞄准的是人们出行时的需求,机票、酒店、景区门票、攻略、行程安排等等。 主要的玩家是携程去哪儿。最近Airbnb进入中国市场,Airbnb主要的竞争对手是酒店,Airbnb今后的目标是进军整个旅行市场。专注于旅行本身的有蚂蜂窝、蝉游记、面包旅行、氢气球旅行等等。当然携程这样的巨无霸App中也是集成了旅行相关的功能的。 综上,旅行市场看起来还是比较简单的,酒店机票业务实际也属于O2O的范畴。最近Airbnb的兴起,应该会为这个市场带来一些变化。 教育 在线教育这个市场,是近几年随着MOOC的发展而发展的一个市场。这个市场可以分为几种: 职业培训(网易云课堂,特别是里面的微专业) K12教育(比如百度作业帮、小猿搜题) 资格培训(各种托福雅思公务员驾照App,比如猿题库) MOOC(国内的有学堂在线、中国大学MOOC,当然也包括Coursera和edX等等老玩家) 科教类(比如榫卯,烧杯以及各种以交互式的科普知识为目的的App) 英语类(这类应用也属于广义的工具类应用,背单词是为考试服务的,因此也可以说是属于前面提到的几种类别,但因为需求最大,因此可以单独讨论,主流的比如英语流利说、扇贝单词和百词斩) 有部分应用会同时做职业培训、K12、K17(高考)等等方面,比如有道精品课。 目前中国中产阶级越来越多,消费升级表现之一就是对于教育的投资。线下和线上的教育市场都会被拉动起来。 内容类 视频/音乐类 视频和音乐类应用的历史很悠久了,这里说的是提供视频和音乐服务的产品。视频方面有优酷土豆、PPTV、乐视、搜狐视频等。音乐方面有QQ音乐、网易云音乐和虾米音乐。 互联网时代,中国的视频和音乐市场最关键是就是版权之争。10年前版权宽松的时代已经一去不复返了。现在的视频网站的资源主要来自版权的购买。 除此之外,自制内容也是很火的。国外这方面最典型的就是Netflix。国内比较典型的就是乐视自制的《太子妃升职记》,还有之前在优酷上火的万合天宜系列的网剧。目前国内比较流行的模式就是拿一个IP(知识产权,比如畅销小说)改编网剧(因为国内IP不够优质,最近开始改编日剧,不过质量实在是惨不忍睹)。个人觉得目前来说国内的文化产业还是比较浮躁的,比较着急赚钱变现。 音乐市场上,网易云音乐也希望能挖掘草根音乐人并与其达成合作,在残酷的版权竞争之外另辟蹊径。 资讯类 资讯类包括了老牌门户网站新浪网易搜狐的新闻客户端,以及新秀今日头条和UC等。今日头条和主打的是个性化的推荐,UC则是用其独特的编辑风格,吸引了很多人的眼球。...

March 27, 2017

终端工具翻墙不完全指南

写这篇文章的动机是之前Github曾经短暂的被墙过,这样的话,如果终端没有翻墙,那就没法推代码了。之后几天国内访问Github也一直很慢,于是尝试了给终端翻墙。网上的文章很多,但没有特别满意的,因此决定自己写一篇。 说是不完全指南,因为我这篇文章针对的是macOS下使用Shadowsocks翻墙的用户来说的。当然其他其他的系统,如果是使用Shadowsocks,道理应该差不多。 预备工作:安装Shadowsocks客户端,配置好服务器。搞清楚Shadowsocks在本地运行的端口,一般是1080或者1086。 Homebrew翻墙 macOS下装软件要用Homebrew,但Homebrew的源在国外,国内用是很慢的。首先我们要让Homebrew翻墙,才能顺利的往下进行其他工作。 Homebrew下载用的是curl。因此我们只要配置curl使用代理就可以了。 curl的代理在~/.curlrc 我们在这里加一行: socks5 = “127.0.0.1:1080” 1080是之前说的Shadowsocks的本地端口,下文就不再说明了。 安装Polipo brew install polipo 装好后记得把之前加上的curl的代理删掉。 然后配置polipo,修改/usr/local/opt/polipo/homebrew.mxcl.polipo.plist设置parentProxy: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>homebrew.mxcl.polipo</string> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> <key>ProgramArguments</key> <array> <string>/usr/local/opt/polipo/bin/polipo</string> <string>socksParentProxy=localhost:1080</string> </array> <!-- Set `ulimit -n 20480`. The default OS X limit is 256, that's not enough for Polipo (displays 'too many files open' errors). It seems like you have no reason to lower this limit (and unlikely will want to raise it)....

March 26, 2017

聊聊云计算

这篇文章主要是写我对团队在云计算方向上现状的一些思考。并没有什么关于云计算的干货,毕竟我在这方面还需要大量的实践才能有足够的发言权。 IaaS 我们用的最多的就是IaaS(Infrastructure as a Service)了。阿里云中的ECS和RDS就是典型的IaaS,另外阿里云OSS或者亚马逊S3那样的存储服务也是。 IaaS,简单的理解就是,将计算资源,作为一种基础设施,提供给用户。用户可以像消费水和电一样来按需进行使用计算资源。 IaaS是基于虚拟化和分布式技术来提供服务的。在云计算之前的时代,公司的网站是部署在一台台实体的服务器上的。一般来说,一家小公司,可能只需要一两台服务器就可以满足业务需求了。有服务器也自然有传统的运维人员,这种工程师精通硬件、网络和安全方面的知识,全权负责机房里服务器的正常运转和性能优化。 然而维护一台实体服务器的成本是很高的,需要雇佣一个服务器运维人员,需要付出电费和购置服务器的费用,以及架设网络的成本。 大公司会建立数据中心,其实就是有着大量服务器的厂房。大公司有着足够的人力去维护自有的服务器。 在那个年代,后端工程师部署服务是直接部署在实体机器上的,在部署时需要和运维人员确定服务器的环境等,经常会有一些沟通上的问题。 还有一个问题则是,那时的网站是很难动态伸缩的,一个应用往往同时部署在多台服务器上。然而,要使得一个服务能抗下更多的流量,就需要更多的服务器,如果不能在短时间内配置好新服务器,网站在压力之下往往会崩溃。 云计算对于小公司的好处在于,消除了维护实体服务器需要的各种繁杂的成本。维护实体服务器的责任交给了云服务厂商。小公司只需要购买服务就可以。 对于大公司来说,云计算可以动态扩容,一键部署,使得应用在压力之下可以弹性伸缩。将计算资源利用率最大化。 我们使用的ECS其实并不对应一台实体的服务器,但我们在使用的时候可以将ECS当成一台完整的服务器来使用。这就是虚拟化技术的好处。我们可以按需使用计算资源(一台实体服务器往往是8核或者16核CPU这样的配置,我们用不到这么多的CPU)。 我们也不用担心服务器会被攻击或者数据丢失。ECS提供了自动快照的服务。 在我看来云计算是对计算资源做的一次抽象,将后端应用和实体的服务器硬件资源隔离了。使得基于硬件的备份和维护这些事情抽象出来,开发人员只用关注应用层面的逻辑就可以了。 而RDS和OSS这些服务,也是同理。我们不用关心存储具体的物理位置在哪台服务器上,只需要调用这个服务就可以了。 而RDS、ECS和OSS三个服务的分离,也是一种抽象。ECS只关心业务逻辑,OSS和RDS只关心数据存储。只有无状态的服务才能轻松实现横向的拓展。如果ECS上的应用和数据库一起部署的话,会对应用的可拓展性造成影响。 具体说到我们团队,ECS和RDS我们使用阿里云的服务。对象存储我们则打算自建。一个是利用手上的物理服务器,降低一些成本,还有一个就是研究一下分布式存储相关的技术,加深团队在云计算方面的技术深度(Ceph这个开源的分布式存储框架已经非常强大了,我们目前打算先尝试Ceph)。 PaaS PaaS(Platform as a Service)方面的服务的代表就是Google的App Engine(以下简称GAE)。在App Engine中你只需要写业务逻辑,不需要关心服务和数据的部署。GAE号称会根据你应用的流量实时拓展服务的部署。 GAE带来的其实是更高的一层抽象。将基础设施的使用也屏蔽了。其实这个就将当于大家写了一个Flask应用,push到Github,写一个简单的配置文件,然后就可以访问了。你不用关心Nginx的配置,也不用关心部署多个实例以及均衡负载这些问题。It just works。 另外你还可以在控制台用GUI控制你的应用,以及读取监控数据等等。 我对此是非常感兴趣的,特别是Docker的出现,使得自动化的部署,环境的隔离以及标准化变成了一件比较简单的事情。 我构想中的Muxi App Engine(以下简称MAE)是这样的: 支持Python和Node两种环境,会根据ECS上的实时部署情况,自动将容器实例部署在最合适的ECS上,并且在流量变大时会自动伸缩。在MAE控制台上可以看到常规的Log统计。可以在MAE上用配置中的Git仓库和分支进行一键部署,前端代码也是一样的。 MAE的目标是将一些应用公共的流程尽量标准化,目前我们的自动化部署还是需要自己写Webhook脚本的。统计的话也是需要手动去配置的。Nginx相关的一些配置也是手动的。 MAE是一个单独的服务,部署在一台服务器上。MAE对可支配的ECS都有着记录,并且在对应的ECS上都运行着守护进程,和MAE服务通信。 MAE时代的开发和目前并没有太大的区别,只是每个应用需要有一个MAE的配置文件,里面写了域名、Github仓库、Docker环境等等信息。 我们在MAE上新建一个应用,然后点击部署,就可以部署了。 对于我们的大部分,自己托管数据的应用(相比匣子这样需要实时爬取的应用),比如学而、桂声等等,MAE这样的模式可以很好的讲平台层的运维工作简单化、标准化。 当然MAE如何和微服务结合这个也是一个问题,目前的应用其实是有分拆成服务的空间的,这样的话MAE其实应该是以服务为单位的。 SaaS SaaS(Software as a Service)离普通用户最近的云计算形式。我们用Tower、百度云盘、石墨文档这些,都属于SaaS。 我们日后推出的服务,比如云简历,或者是其他工具类的应用,都是以软件形式向用户提供了某种基于云计算的服务。 结语 基于综合的考虑,我认为云计算是目前最有用,也是最触手可及的前沿技术。 目前后端技术这边,机器学习/人工智能、云计算、大数据,是几个比较火的领域。当然这几个领域目前有融合的趋势。 对于我们来说,要构筑我们的技术壁垒,云计算是最好的突破口。在知识水平、业务体量等种种的不利因素下,云计算是可以深挖,并且实践的一个领域。 无论是对于我们内部服务的支持,或者是对于个人技术能力,就业市场竞争力的提升来说,这都是一个最优的方向。 所以在接下来的很长一段时间,我希望大家能一起努力,在云计算上,达到一个不算太寒碜的水准。这需要所有同学的支持,包括前端、客户端和设计组的同学,因为转向云计算会对目前的开发流程产生很大的影响。然后在UI和品牌方面,自然也需要前端和设计师的配合。PM同学也需要理解这个战略。 就写这么多吧。祝一切顺利。

March 21, 2017

我的2016

2016对我来说当然是很神奇也很重要的一年。团队的进步很快,华师匣子终于上线。我也顺利的找到的工作。 回想这一年,对于上半年的事情,现在只残存着一些依稀的回忆了。这一年我对前端的理解,有了很大的变化,这其实是一个日积月累的过程。所以Tower里的进度,对于我来说,就是一个非常好的备忘录。自己的学习的历程,在里面可以看到一个很清晰的脉络。 回看我的进度,1月的时候我开始写简历生成器和学而的后台,那段时间我对于前端工程化很痴迷。把Dan Abramov的视频看了很多遍。主要用React写东西。 寒假主要是写学而后台,写个人主页,看YDKJS和《JavaScript忍者秘籍》。寒假里面我发现了大批的电子书,对于JS的语言有了更深入的了解。也开始对公司和业务有一些自己的思考。我对于浏览器的探索也在那个时候开始了,主要是看了Mozilla工程师写的自制浏览器那一系列的博客。从进度上来看,那个时候真是热火朝天的学学学,新事物扑面而来,整个人还是很有干劲的。 在找工作这问题上,当时我还是很没有底的。 那段时间还在刷PAT,打算去参加春季的考试,但最后还是没有去,觉得没有准备好。 接下来就是3月了,开学了,要上课要辅修,事情很多。学习的进度就没有那么快了。 3.14 投简历+学而+团队+i华大 = 爆炸 后来就是接触简单的算法,去网易面试。 4月学校的出版社实习期间开始看jQuery源码。 找工作 3月开始面试,第一个面的是阿里,二面挂了,一些很简单的问题没有准备,比如正则和简单的DOM API。后来面了饿了么,过了。在面试网易的时候,饿了么表示如果不能确定offer那就算了,于是我就在没有保底offer的情况下,去网易面试了。 去网易的面试算是我第一次很正式的面试。总的来说,其实很平稳,但对我来说,记忆犹新。最让我感到印象深刻的还是面试期间那种忐忑的心情。好在最后一切顺利。现在看来,觉得还是挺幸福的。 团队 5月份的时候,团队出了大事,主要就是工作室要装修。领导为了面子工程,把我们的304改成了展示厅。对当时的我来说这真是和晴天霹雳一般。 匆忙的租了房子,其实最后也没起多大作用。这次搬家对我们来说,意味着很多。和过去告别。真正的成长,担起团队的责任。 这个时候,我们确立了核心成员的概念。一个团队,只需要核心成员,不是核心成员的都可以离开了。一个团队的人数并不是关键,团队的凝聚力和战斗力才是最关键的。 其他的话,其实从我进度里看,关于团队的很多。大部分都是一些消极的抱怨,还有一些思考。暑假的时候,和大家远程交流,开会。很困难,到最后其实很有多的摩擦。但无论如何,事情都算是过去了。 在12月的时候,我决定从团队的日常事务中抽身,专心做自己的事情。经过这段时间来看,团队是可以自己正常运转的。很开心啊,像是自己的孩子长大了一样。 在网易的三个月 在网易的实习经历,在业务上是比较平淡的。做的有数这个平台的确是很复杂的,但我加入的时候这个平台已经比较成熟了,所以也没有太多挑战性的东西。没有见证初期的技术选型和架构的选择,所以在这方面没有学到太多想学到的。在大公司,技术选型这个是一个多方博弈的结果,要考虑公司本身的基础设施,并不是简单的引入开源项目就可以的。 在网易主要是写了一个Regular-devtool,其他的话就写了一些简单的业务。生活的话,可以说还是非常幸福的。环境这些都挺不错的。现在想来还挺怀念呢。 华师匣子 这个可以直接看之前写的华师匣子开发记 一些新的探索 函数式编程,以及相关的一些,还有编译原理。这两个Topic是我下半年的核心。这是我最近觉得最感兴趣的方向。对这些方向只进行了一些初步的探索。 前端工具上,7月我写了Ninja,在团队的项目中用了半年。说实话这个是我最自豪的事情。 12月开始写Build your own Vuejs,希望能顺利写完。 未来打算 我现在的一个理念,就是,你想学什么,那就自己写一个。光用是不行的。比如像了解前端MVVM框架,就自己实现一个。想学编译原理,可以自己实现一个简单的编译器。我认为这是很有趣的事情,也是很了不起的事情。 未来打算在前端工具和框架这个方向上深入的研究。然后正式学习函数式编程。以及DSL相关的知识。保持好奇心。保持对生活的热爱!

December 26, 2016

从0到1:我和木犀的故事

缘起:华大桂声技术部 2013年10月我加入华大桂声技术部。其实一开始我加的是华大青年,但因为那里没有专门的技术部,面试的时候也没有做技术的人面我,所以我在得知桂声招新的情况下,放弃了华青那边的录取。 于是就开始了在桂声技术部的日子。那个时候其实i华大已经建立了,但桂声还是比较强势一些。那段时间主要就是在一个2011级学姐的带领下做桂声的专题和网站。我记得我来的那年之前做了110周年校庆专题和迎新网,都很不错。桂声的专题是很有特色的,现在我们也试图去捡起这个传统。 我接到的第一个任务是做一个恽代英专题,在炳权学长的指导下,顺利的做出来了。关于这个我记得比较清楚的细节,一个是熄灯了之后搬个凳子去走廊里做,还有一个是上线了之后很兴奋,发给很多人看。 接下来就是下半学期开始的桂声改版,我写了一部分的主页。那个时候,我其实压根就不会写真正的代码,如果要用到JS,比如轮播图,我就去网站下一个功能差不多的插件,然后修改一下。这个过程其实是很痛苦的,因为你心里并没有底。所以每次把插件改好都像是一场战役。 一个人的i华大技术中心 2014年开始,虽然我们还是习惯说自己是技术部的,但名义上已经是i华大技术中心了。底下分技术研发部和视觉设计部。 说一个人,我指的是技术方面,设计那边还是很强大的。除了做主任的学姐和炳权学长,其他人并不会技术,然后之前的主任学姐三四月份就跑路了,炳权学长也很早就在名义上退出了。因此这个技术部就只有我一个人了。 然后就是2014年四月份,技术中心春招。我依稀记得那个时候来了有大概三四十号人。然后我在306做培训,其实就是教他们切页面。 那个时候也没想着要做一个技术团队,就想要把技术中心做好吧。当时我自己其实也是小白,也教不了他们什么。这三四十号人也并不是完全合适,因此最后待的比较久的,就只有龚红霞一个人。 2014年的上半年还发生了一件事情,就是桂声10周年庆,请了很多高校的团队来交流,有武大和理工人的来了。当时我们的技术实力几乎为0,然而却在PPT上写了我们用Node,现在想起来还是觉得脸红。我听他们讲JSON,API这些,完全不懂。想来这应该就是我想打造一个技术团队的最初来源吧。 木犀! 木犀这个名字,想来应该就是14年下半年提出的。之所以叫木犀,是因为华师的桂花很出名,但直接叫桂花又太俗。我偶然得知木犀是桂花的学名,于是就选用了这个名字。 这里有个插曲,炳权曾经提议说我们可以叫handle,现在想起来还是觉得很搞笑。 2014年的秋招,来了很多人,胡薇、韩伟、老王、王露晨、梁晓怡,这都是之后设计组的核心,想来之后那段时间也是设计组的黄金时代。小桂漫画,壁纸,表情,都是那段时间做的。 还有一个人,那就是朱承浩。 对我建设团队帮助最大的还是炳权,因为炳权那个时候已经在冰岩了(虽然我到15年上半年才知道),他会给我们很多建议,我也拓宽了很多视野。 2014年下半年我们开始学Python,决定用Python做后端的语言。但那个时候还没有能力去完成一个网站的后台。那段时间我主要是用Drupal这个CMS来做学而的第一版。 学而第一版其实反响还是很不错的,现在数据库里都还有那个时候的评论。这对我来说是一个鼓励,说明产品是有需求的。然后Drupal这个东西,开发难度很大,这坚定了我们自己学后台的决心。 2015年的到来,是一切奇迹的开始。放弃Drupal和各种前端插件,真正的踏入Web开发的大门,就是从哪个时候开始的。所以说木犀的成长史,也是技术的成长史。 首先我们在15年2月全面使用了Tower(这个时间点之前设计组好像就已经在用了)。大家看我和承浩的进度都是从15年2月开始的。至于Tower,对,没错,是炳权告诉我的,因为冰岩在用。 之后就是承浩的时间了。他学了Flask,我们用Flask搭的第一个网站是什么,我已经忘了。我只记得那个时候,光部署网站,就要花好几天,因为书上讲的是AWS这种云服务的部署。手动的部署还是有一些门槛的。那个时候,因为了解的层次比较低,会觉得很多东西是玄学。 3月我们去了联创交流,具体可以参见我的这个博客。 5月份和6月份其实还有一次转折。5月份的时候,理工的token团队办了十五周年庆,我们去参加了技术交流会。这次是我们第一次以木犀团队的名义出去交流。也是从2015年上半年开始,我们慢慢习惯以木犀团队的身份出现在所有人的眼中。这次交流会上,我们依然没有太多的干货,相比于其他团队,我们感受到了我们还太年轻。 6月联创Hackday。我们主要是去感受了一下气氛。3月和6月两次去启明,对于我和承浩两个做技术的人来说,这个冲击不亚于工业文明对封建社会的冲击。首先是感受到了华科那边浓厚的技术气氛,其次是感到了一些压力,因为我们团队是如此的弱小,而华师的技术氛围又不想。当然是压力也是动力,不管如何,从2015上半年之后,我们团队在技术上便开始了不断的进步。 联创Hackday (图片找不到了) 暑假承浩买了Mac,从此就一发不可收拾。那个暑假我在极验实习。其他人进行了我们第一次的夏令营(夏令营这个想法也是炳权提供的)。那个夏令营还是很愉快的,我们做出了第一版的内网,对于Flask的掌握已经好很多了。 夏令营照片: 夏令营最后去落雁岛玩的照片: 2015年9月,团队已经初具规模了。后面的事情,15级的同学应该都清楚了。 接下来的事情就是2015年下半年开发的学而的第二版,完全用Flask写,有同步的路由和REST API组成,前端移动版是一个SPA,用了Webpack和React。这就是我们第一个工程化的产品。 技术团队的成长,其实就是我的成长,承浩的成长,已经后面14级其他同学和15级同学的成长,每次有一个人成长为核心成员,团队就变的更加的强大。 番外:304-306-502 一开始,i华大技术中心的办公地点是在304。那时候我们还是非常自由的,304可以随意的改造。经历过那段时刻的同学应该知道,那段时间是很有归属感的一段时间: 直到今年5月份,304和306装修。我仓皇中去合租了一间房子,在教工宿舍,作为我们的临时工作室: (图片找不到了) 那段时光是难忘的,也是别扭的,痛苦的。那只狗,上门的邻居,狭小的空间,和我自己当时的各种压力混合在一起。 现在我们主要在306活动,也在304。虽然归属感没有以前这么强了,但因为大家更熟悉了,核心成员也更多了,所以团队的气氛要更好一些。 我还是希望我们能有一间独立的工作室。我们要时刻保持危机感,来应对未来的无限的可能。 前端之路 我个人的前端之路,其实也是木犀从0到1的一个很好的注脚。 我其实在15年的上半年才开始正式学计算机。那个学期在武大开始辅修,然后在团队开始学Flask和Python。5月的时候,我的前端水平是只会写简单的Banner,相比之前Banner都要用插件的水平来说,算是好一些。那个时候是标准的过程式的编程。 5月的时候看了一本单页应用开发的书,里面讲到了IIFE,闭包等等。我如获至宝,写个什么组件(其实我当时并没有组件的意识)就用IIFE,其实这算是最初的模块化,工程化意识吧。只不过我那个时候并不清楚模块化和工程化,也不知道正常的编程语言都是自带模块的。 7月和8月我主要在极验实习,切了不少的页面,里面有一些用jQuery做的组件。这个时候我写展示型的页面以及比较熟练了,CSS也掌握的不错(毕竟在写桂声那些主要就是CSS)。但对于前端的那些Grunt什么的工具,其实我并不是很清楚为什么要用。 所以对于模块的理解,对我来说是一道坎。真正理解模块和工程,还有闭包,大概是今年的事情了。 9月回学校之后我看了React,后来就开始用Backbone写学而。那个时候我对MVC了解的还是比较多的,因为之前后端用的就是MVC。写React的时候比较初步的理解了组件化。之后对于Webpack之类的工具也用的很顺手了。 这个学期对面向对象也略有了解。但对于View和Model的分层,以及组件的抽象,还没有到能手写的地步。那个时候我看Backbone源码,并没有太多感觉。而现在我回头看,就觉得抽象非常的清晰了。 那个时候我对很多事情的理解都比较的浅薄。对于React Native很崇拜,觉得Web的目标就是取代原生应用。觉得Web就是要做单页应用。也没有很深入的理解前端工具为什么存在,以及组件化的发展史。 现在来看,其实Web有Web的特点,需要动态化、快速上线、展示型的东西都可以用Web来做,这只是一个简单的技术选型的问题。 总得来说,这是一个技术视野的问题。如果你用过很多别的语言,那你就应该很容易的理解模块的存在。如果你开发过原生应用,那你就应该很好的理解为什么Web开发的UI应该是组件化的。 今年开始,我把兴趣移到了函数式,编程语言,还有计算机基础上面。对于前端,我主要在开发工具解决我们自己的工作流中的问题,还有就是研究框架和工具的源码,进一步深入。 现在回过头来看,我就能发现前端学习的一个最佳的路径,DOM可以不用花很多心思,但组件一定要自己去手动实现。模块可以直接用标准的模块。前端无非是普通的客户端软件开发,从这个视角去看的话,事情就清楚多了。 计算机基础加上足量的工程经验,应该就可以成就一个好的工程师了。我的前端之路还算顺利,大家的学习道路,在我们这些先行者的踩坑之后,肯定会更加顺利。但有一点是肯定的,要把一样事情学好,需要你的热情,时间,和精力。 还有一点,就是你的视野是随着你的经验而增长的,视野对你理解一些技术是非常有帮助的。平时我们在安排学习路线时也会特意的去安排背景阅读材料,或者是讲一些思想和Lab结合起来,努力让大家能够尽快的熟悉那些方法论层面的东西。同时,你自己的思考也是离不开的。我经常会思考,踱步。好的书常看常新,经典的思想,也是需要反复的思忖才能领悟的。 我们在路上,前方不会太远 2016年,团队最大的新闻当然就是华师匣子的上线。这个是我们的第一款移动应用,也是将来一切产品的推广基础。 在我看来,团队最大的成长,一个是技术团队在工程化上慢慢摸索,有了自己的方向。我们的方向就是通过造轮子来深入原理,积极的实践最新的技术,写完善的文档,在社区中争取拥有一定的影响力。 在团队的管理上,确立了早读制度,试行了导师制度,管理工作组共同管理团队,成功的进行了秋游,招新算是顺利,团队管理层平滑更换。这些都是一个团队平稳运行的基石。如果说这个大框架搭好了,我们就可以把精力投入到具体的产品和新人培养中去了。 在接下里的日子里,我们要把产品的汇报制度完善,项目组的气氛要更好,全员大会要常态化,组内技术积累要抓紧,新人双轨培养的计算机基础方向需要花很大的力气建设,UED部门要重新上路。 对于团队的期望,我不想说太多,我只能说,作为一个木犀人,你就算毕业了,也依然要参与到团队的建设中去,只是不在第一线了而已。只有这样才能慢慢的把事情做好。我们追求的是理想中的团队,可能我们永远都无法到达那个理想中的境界,但一直在成长,一直在进步的话,大家开开心心的,就挺好。 我们在路上,前方不会太远。

December 19, 2016

华师匣子iOS版开发记

这个月华师匣子的iOS版终于上线,历时四个多月的开发告一段落。我达成了从客户端开发0基础到App Store的成就。四个多月,99次提交,10个内测版本,两次App Store发布,这实在是一个值得纪念的时刻。 这是匣子iOS的Github提交图表: 上个学期我接下iOS版开发的任务时,其实我心里是没底的。没学过iOS是一方面,关键是我也没有任何客户端开发的经验。当时我对客户端开发的了解几乎为0。之前有接触过一点安卓。但iOS这边玄学的StoryBoard和新语言Swift都让我比较没底。 起步 我首先看了斯坦福的iOS开发课程。这个课程是一个非常不错的课程。里面实现一个计算器,代码的结构非常的合理,也充分发挥了Swift的特性。当时我的感觉就是,写APP或者其他业务并不是会调API就好,如果想要写漂亮的代码,那还是需要扎实的计算机基础。 我看着课程,但我并没有跟着写,因为时间不多了。我在了解了基本的MVC架构、StoryBoard中拖控件、拖Outlet和Action、Auto Layout之后,就开始写匣子的几个界面。 当时写了界面之后,就有所感触了。首先Auto Layout的确是一个非常好的布局方式,让我不再怀念CSS。然后,原生APP中首先所有的组件都是有与之对应的对象实例的,这是顺理成章的事情。但在Web这边,组件需要自己抽象,而且在Web Component没有普及之前,没有原生级别的支持。写iOS的过程中我越发明白,DOM其实只是Web界面UI的实现细节。我们要用某种方式去封装DOM,在UI抽象层编写代码。iOS就完全符合这种方式。想来客户端软件理应是这样的。只不过Web技术从一开始并不是为客户端软件打造的,因此这几年前端走的路,基本就是补上之前落下的课。 当然Web前端数据驱动,双向绑定这些,在我看来已经是最前沿的东西了。iOS这边肯定也有。但因为我对前端更了解一些,所以觉得前端要更优雅一些。 最开始做图书馆,于是就遇到了输入框键盘如何收起的问题。点击return,点击屏幕的其他地方都会收起键盘。这里要提到一点,就是这次0基础做iOS,是我第一次在全英文的环境下从头开始学一门技术。这次我全程一行中文都没有看。回头想想,很难想象如何在中文社区解决这些问题。 深入 接下来就是各个技术点的学习了。数据持久化要用Core Data,其实就是一个本地的SQLite数据库。这个我基本是当Key Value存储来用了。对数据库还是不是很了解。然后有触摸事件的处理等等。网络请求用Alamofire和SwiftyJSON。学用iOS的Cocoapad装依赖。 学习的过程中,说起来只有一个比较理论的知识,就是delegate、protocol、extension这些。 之前在看斯坦福课程的时候还不是很了解。后来用UITableView以及需要不同VC直接通信的时候,就慢慢了解了delegate。我对delegate的了解就是一种委托的模式。任意一个实现了对应接口的对象都可以作为委托的对象。后来在安卓那边了解了一下,大致有同样的实现。 UITableView实在是一种很经典的接口设计。除了那几个delegate方法之外,UITableView会对Table Cell进行回收的做法,也让我明白了之前面试时问我的长列表优化问题的答案。在Web端我们也可以控制列表只保留可视区域的DOM元素,来做优化。这样不管列表有多少元素,都可以顺利的渲染。 课程表 课程表一度是我迟迟不愿意动手的一个模块。其实匣子里大部分模块的逻辑都是简单的查询和拉取数据。课程表也不例外,但课程表的View相对来说比较复杂。我咨询了安卓的同学之后才知道要自己画View,自己handle触摸事件。于是就写了一个双向的滑动,在触摸事件中修改View的偏移。 画课表的格子也花了我一段时间,最后算是解决了。后期还要再完善。课程表的实现让我得以一窥iOS开发的常态———自定义View。实际上大部分的控件应该还是需要自己来写的,毕竟大家的APP看上去都很Unique。 iOS的View可以自定义drawRect方法。这应该就是暴露了底层的2D绘图API,类似于Web中的Canvas。 收尾 其他大大小小的问题还有很多,比如我一度纠结于如何取消Navigation bar上面返回按钮的文字,结果发现在Story Board里面的Back Button打一个空格就行了。踩了很多坑,有一个很大的坑就是我一度用中文做了包名,导致后来数据迁移一直报错。 Banner的话,最后是用原生的UIPageView实现的。之前一度以为要自己实现一个。想来自己的水平还是不够的。 后期陆续完成了数据迁移,远程推送,本地推送,闪屏处理,还有和后端元信息API的整合。 上线的时候,担心我们的服务器不支持IPv6,担心不会过审。不过最后很顺利的过审核了。苹果的工作效率没有想象中的那么低。 苹果要求HTTPS和IPv6,Safari10支持全部ES6属性。这意味着苹果一直走在时代的最前沿。在这一点上我要给苹果点赞。 这次iOS的开发算是让我获得了iOS的初级开发经验,点亮了客户端开发的技能点。为后续我的Hybrid研究开了一个好头。 关于Swift Swift给我的印象还是很不错的。静态类型,经典的面向对象,外加和JS类似的函数式特性,我用起来觉得很顺手。OC看起来太恐怖了,如果不是有Swift,想来我也不会鼓起勇气去写iOS。Swift未来还会进军服务端,虽然是Apple自家的东西,但开源了,想来发展应该会是不错的。

December 19, 2016

Build your own Vuejs Chapter1 Vue Overview

In the book Build your own Vuejs, we will build a Vuejs from scratch. And you will learn how Vuejs works internally, which helps a lot for your daily development with vue. Inspired by the amazing book Build your own Angularjs, the code of Build your own Vuejs will be developed in a test-driven way. We’ll focus on Vuejs 2.0. And we assume our reader have played around with Vuejs once and know basics about Vuejs APIs. ...

December 12, 2016