Blog | Phodal - A Growth Engineerhttp://www.phodal.com/blog/2020-12-28T11:38:15+00:00Blog论程序员成长:如何像游戏一样打怪?2020-12-28T11:38:15+00:002020-12-28T01:39:21.559801+00:00Phodal Huanghttp://www.phodal.com/blog/author/root/http://www.phodal.com/blog/growth-path/去年年底,在回顾那几年的 Tech Lead 生涯,以及对新 Tech Lead 的培训时写了那篇 《[Tech Lead 的养成](https://www.phodal.com/blog/how-to-be-a-tech-lead/)》。在新的团队稳定了下来之后,我开始寻找下一个合适的成长路径,或者说是模型。因此,从某种意义上来说,这是一篇写给自己的文章。
最近,我在探索中发现公司内的各种 Growth Paths(成长路径)已经成熟了,比如我试着重新对比一下其中各类的模型,Technical Anchor。那么,我的下一个阶段是不是应该与 PRINCIPAL ENGINEER 相挂钩?
## 职级并非与能力挂钩
PS:我只在 ThoughtWorks 待过,所以我对其它公司的职级体系也不是非常了解。所以,其中的部分内容来源于:我在和客户一起工作时所总结的,还有网上所看到的资料。
职级是**在某一组织内部**,将工作内容、难易程度、责任大小、所需资格皆很相似的职位划分同一职级。
对于大部分公司来说,职级体系必然与薪资体系相挂钩的。你的职级越高,你要做的事情 level 更高,那么你的**应得**收入就越多。即从理论上来说,你创造的价值越大,那么你所获得的收入就越多。比如说,程序员 A 写了某个业务系统的关键代码,这个业务系统非常成功,那么你创造的价值就远比另外一个程序员 B。(PS:但是实际上并非如此,有可能不会伴随你产生的价值)。
与此同时,A 之所以拿的工资比 B 高,并非因为 A 的编码能力比 B 强很大,又或者是因为 A 的其它能力比 B 强。而是因为 A 刚好出现在一个合适的地点上,所以 A 有了更多的职级和更高的收入。
当然了,那些在 BAT 996 的程序员,能力都是比我强的。
## 职级与能力:外在与内在职业生涯
PS:在写文章的过程中,我看到了一个更专业的词汇:外在职业生涯与内在职业生涯
- 外职业生涯(对外在职场而言),是指从事职业时的工作单位、工作时间、工作地点、工作内容、工作职务与职称、工作环境、工资待遇等因素的组合及其变化过程。
- 内职业生涯(对个人自身而言),是指从事一种职业时的知识、观念、经验、能力、心理素质、内心感受等因素的组合及其变化过程。
多数人在他/她们的职业生涯间,都要面对着各种各样的角色变换。或是从开发人员变为产品经理,或是从测试人员变为项目经理,又或者是从程序员变成滴滴司机。在过去的几年里,我也面临着一些细微的变化,如从开发人员变为技术负责人,从交付项目来到咨询项目……。唯一不变的是,写代码还是我日常的主要活动,但是我需要提升其它能力。
简单来说,内在就是你想做事情,外在的就是你做的事情。这两点的平衡是一件非常有意思的事 —— 尽管我一直平衡不好。
## 角色成长路径
每个成熟的公司都有对应的职级路径,至于划分的好坏就是另外一回事了。晋升就是与职级路径相匹配的活动,它会伴随在我们的外在职业生活中。而这部分的内容不是这篇文章的主题。
回到标题上来,看看 Technical Anchor 角色的定义:
> 具有丰富的技术和行业知识的领导者,沟通者和工程师。 能够提供技术合作的信心和方向。 他们拥有解决方案和技术堆栈的设计和架构,从头到尾对其进行指导。他们专注于确保团队内部战略的成功实施
这是一个角色,并非与真实的职级挂钩。这个角色定义的能力有诸如于:
- Technical visioning and roadmapping
- Evolutionary Architecture
- Integration
- ……
但是呢,Technical Anchor 的定义上和我去年定义的 Tech Lead 最大的区别在于:这个角色要花 70% 的时间在代码库上,而 Tech Lead 要花费的只有 30%。Tech Lead、Tech Anchor 以及 System Architect 相当于是这个第二级角色。
PS:一级角色就是具备完成工作能力的成员。简单来说,对比如下:
- 新手 vs 普通程序员
- 骑士 vs Tech Lead 等
- 圣骑士 vs Principal Engineer 等
这个过程,非常有意思,我们要围绕的是能力成长。换句话来说,我们需要练习打更强的怪,才能获得职业成长。如我司定义的 **Principal Engineer **
> A Principal Engineer is a highly experienced technologist who drives the success of a complex engagement through the depth and breadth of their engineering skills.……
它要做的事情是**推动复杂交付的引擎室**,对应有一些关键能力:
- Legacy Mitigation
- Application Architecture
- Cloud Native Architecture
- Back End Development
- Distributed System Architecture
- ……
如果每一级都定义好了,那么我们只需要有针对性地提升能力,并进行实践即可。
## 其它
整个过程中,唯一麻烦的点在于,如果在一个组织内部,只有职级,而没有成长路径。那么,就需要从社区上来获得对应的能力模型,才能想着配套上对应的练习。Tech Lead 的养成2019-12-02T11:21:31+00:002019-12-02T11:22:03.769352+00:00Phodal Huanghttp://www.phodal.com/blog/author/root/http://www.phodal.com/blog/how-to-be-a-tech-lead/半年前,公司出了一个计划,目的大抵是培养下一任 Tech Lead。作为一个勉强算是资深的 Tech Lead,我大概是能承担这样一个工作的,所以我成了 coache 中的一员。
不过,既然花了挺多的时间,做了这么样的一件事,那么我还是得写一篇文章总结一下。
开始继续往下阅读之前,我先声明一下:
1. 内容是基于硬技能相关的。
2. 部分内容不完整,只是对内容的细化。详细的部分可以参加:《[迈向 Tech Lead 之路](https://www.phodal.com/blog/path-to-tech-lead/)》
3. 内容来自于公司的经验,可能不适用于其它公司。
## 过程
当然了,开始之前我们需要再澄清一下,我们所说的 Tech Lead 是指一个 role,它既是开发,又是架构师,还是一个领导者(Leader,非领导)。过程中,发现一个比较通用的模式,每个 coach 以自己的风格来培养自己的 coachee。对于大部分人来说,看书都是没用的,培训也都是没用的。而对于一个 Tech Lead 来说,练习远比其它东西要重要的。
所以,有几个基本的模型:
**从真实项目中练习**
- 参与 Inception 的相关工作(架构设计、业务流程、等)
- 参与 Iteration 0 的相关工作(搭建框架、CI 和 CD 等)
- 在项目中实施相应的 Tech Lead 职责
**提升自我的练习**
- 构建知识图谱。
- 应用脚手架。
- 架构设计与架构图。
**输出强化输入**
- 整理图谱
- 输出文章
- 输出 Session
大概就是这么一些,剩下的我再想想。
## 成长模型
对应的,我从众多的 Coach 的实施计划中,提取了一个基本的提升原型。
定义:
1. 需要经常指导,不能独立完成
2. 基本独立工作,需要经常检查
3. 值得信任,可以指导别人
4. 该领域专家,可以解决复杂问题
相关级别:
- level 1:接受培训
- level 2:能用(不能独立,还需要指导)
- level 3:讲 Session(独立完成)
- level 4:组织培训(Drive)
### 微服务架构
书单:《微服务设计》、《微服务架构设计模式》、《领域驱动设计》、《领域驱动设计模式、原理与实践》、《领域特定语言》
**Level 1**
- 参加 EventStorming 培训
- 参加 DDD 战略培训
- 了解 DDD 相关的架构
- 学习典型的微服务架构案例
**Level 2**
- 参与微服务项目 Inception
- 完成单一部分 EventStorming 工作
**Level 3**
- 能主导中小型微服务项目 Inception
- 将成果写成案例讲讲 Session
**Level 4**
- 参与大中型客户的微服务项目售前,并能独立完成 Inception
- 进行微服务相关的 workshop
### 常规软件架构
书单:《架构整洁之道》、《程序员必读之软件架构》、《演进式架构》、《前端架构:从入门到微前端》
**Level 1**
- 参加 TL 培训,掌握 C4 架构设计方法
- 学习典型案例
- 能够绘制系统架构图和部署架构图
**Level 2**
- 参与常规项目的 Inception,并完成部分架构设计工作
- **总结现有经历过项目的架构**
- Spike 具体技术解决方案
- 尝试利用项目做练习,然后评估能否实施
**Level 3**
- 主导一个常规项目 Inception,并把成果写成案例讲 Session
- **搭建项目脚手架**
- **能区分出每种架构优劣势、适用场景**
- 对同事提出的架构方案,会提出意见、问题
- 可以承担架构的技术决策
**Level 4**
- 参与大中型客户的常规项目售前,并独立完成 Inception
- 对软件架构守护自动化
- 了解特定领域最新发展和最佳实践,并能合理地引入项目中。
### DevOps
书单:《持续交付》、《DevOps实践指南》、《SRE:Google运维解密》
**Level 1**
- 有 DevOps 基础,能做 CI/CD 的维护工作
- 了解 Docker、K8S 等容器化技术
**Level 2**
- 在普通项目中项目能承担 DevOps 工作
- 了解云原生架构
**Level 3**
- 能完成项目所有的 DevOps 工作:如搭建 ELK、编写 DockerFile 等
**Level 4**
- 能进入 DevOps 项目承担主力
### 编码
书单:《代码整洁之道》、《重构》、《设计模式》、《从重构到模式》
**Level 1**
- 合理的 TDD
- 了解重构手法
- 了解和实践过常见设计模式
**Level 2**
- 在 Code Review 能发现问题
- 在合适的时候,使用设计模式
- 熟悉 SOLID 原则
**Level 3**
- 具有良好的 TDD、重构习惯和技巧,可以指导团队其他人
- 编码能力能够承担项目所有难度的卡片
- 在 Code review 上可以给出建设性意见
**Level 4**
- 能组织 OO BootCamp 等编程相关实践
### 软件质量
书单:《测试驱动开发 》、《修改代码的艺术》、《探索式软件测试》
**Level 1**
- 能够跟 BA 和 QA 良好协作,正确理解业务需求,代码返工率较低,生产问题较少
- 了解不同类型的测试(测试金字塔)
- 学习如何进行质量诊断,常见的改进方案
**Level 2**
- 对于代码质量有较高的要求,是前/后端测试覆盖率的贡献者
- 对于复杂功能的设计,在质量和稳定性的考虑上略有欠缺
- 注重代码质量,自己花时间搭建起测试框架
**Level 3**
- 设计并实施项目的测试策略
- 在交付过程中设计,并实施质量改进计划
- 进行单元测试相关的 Session
**Level 4**
- 完成多个项目的质量诊断、设计改进方案、测量改进效果
- 发现潜在的软件质量问题,并**驱动**解决。
### 敏捷开发流程
书单:《敏捷软件开发》、《学习敏捷》、《用户故事与敏捷方法》、《精益思想》
**Level 1**
- 了解敏捷软件开发
- 熟悉敏捷软件开发命命周期
**Level 2**
- 对敏捷实践有一定的了解,能够给出一些意见
- 对看板项目敏捷方法产出文字总结,包含看板敏捷方法的优缺点
- 分享看板可能适用的敏捷方法
- 理解和掌握敏捷实践,不断深入扩展自己的技术边界,扩大技术深度及广度。
**Level 3**
- 在交付过程中设计并实施流程改进计划
- 能根据项目需求,因地制宜在项目中进行敏捷实践设计、裁剪及推动。
**Level 4**
- 能够完成多个项目的健康诊断、设计改进方案、测量改进效果
- 能在各个领域综合运用并高效解决问题。
## 结论
没有银弹。荐书《遗留系统:重建实战》:当你面对一坨代码时,你应该这么做2018-01-23T14:16:28+00:002019-12-21T06:58:40.971510+00:00Phodal Huanghttp://www.phodal.com/blog/author/root/http://www.phodal.com/blog/recommend-books-legacy-system-re-enginning/2019.12.21 更新
可以试试我的遗留系统重构辅助工具:[遗留系统重构辅助工具](https://coca.migration.ink/)
----
> 大多数开发人员的主要时间都是花费在与现有的软件打交道上,而不是编写全新的应用程序。
这就意味着,我经常要遇到很多我写的 shit 一样的代码,你经常要遇到很多你写的 shit 一样的代码。不对,别人要经常遇到别人写的 shit 一样的代码。总之,你写的代码可能不是 shit,但是你看别人的可能就是。
先说结论——适合阅读人群:
- **有一定工作经验(2~3 年),并且对代码有追求的程序员**。
- **面向复杂的遗留/旧系统,无法下手的项目**。
- **熟悉面向对象的程序员**
如果你工作 2~3 年,并且遇到瓶颈,也不妨来看看。
引言
---
不过这些并不重要,重要的是,你遇到一坨代码时,你要怎么做?
正确的做法应该是这样的(PS:我整理了两个晚上的图):
![遗留系统:重建实战](/static/media/uploads/legacy-system.jpeg)
对, 这就是这本书的主要流程(前 6 章)。
后四章的内容在讲重构以外的东西,比如自动化开发环境、自动化部署、使用持续集成。很多知识点和工具上,与《全栈应用开发:精益实践》一书是相似的。如果你熟悉书中的 RePractise 一图的话:
![RePractise](/static/media/uploads/repractise.jpg)
很多流程都是相似的,唯一不同的是起点。《全栈应用开发:精益实践》一书的终点,是《遗留系统:重建实战》的起点。我们在之前写了那么多的代码,有一天成为了遗留代码,这些代码可能会到别人的手里,也可能回到我们自己的手里。这时,我们应该怎么做了。
要点
---
考虑到,这本书的内容这么多,并且已经有了上面的那张图,我这里就只列出一些比较重要的知识:
### 进行重构计划之前
1. **先进行探索性重构——使用 IDE、编译器辅助、版本管理**
2. **收集数据来对项目进行评估——性能、错误日志、异常监测**
3. **对常见任何进行计时——环境搭建时间、开发部署、修复bug**
4. **使用代码审查工具,如 PMD、Findbugs、CheckStyles**
5. **使用 Jenkins 和 SonarQube 进行持续检查**
### 重构决策会议
1. 会议应该决定**重构**、**重写**或者**重搭**
### 重构
这一个篇幅里,着重介绍如何识别遗留代码及测试。至于重构相关的内容,可以参见《重构》一书。
### 重搭
方法:
1. 识别业务和重搭范围
2. 定义模块和接口
3. 构建脚本和依赖管理
4. 分拆模块
5. 更新技术栈
### 重写
1. 确认重写范围:黑盒式、温习式、补偿式
2. 从过去学习
3. 数据库迁移:共享或迁移
结论
---
从重构项目中学习,更容易学到新的东西。【架构拾集】:移动应用架构设计2018-01-22T12:11:29+00:002018-01-22T12:12:37.108195+00:00Phodal Huanghttp://www.phodal.com/blog/author/root/http://www.phodal.com/blog/architecture-design-series-design-a-mobile-application-architecture/> 如何 GET 架构设计的新技能
在这一个多月里,我工作在一个采用插件化的原生 Android 应用项目上。随着新技术的引入,及编写原生 Android 代码的技能不断提升,我开始思索如何去解锁移动应用新架构。对,我就是在说 Growth 5.0。
两星期前,我尝试使用了 Kotlin + React Native + Dore + WebView 搭建了一个简单的 Android 移动应用模板。为了尝试解决 Growth 3.0+ 出现的一系列问题:启动速度慢、架构复杂等等的问题。
PS:作为 Architecture 练习计划的一部分,我将采用规范一些的叙述方式来展开。
1. 业务架构
2. 技术远景
3. 方案对比
4. 架构设计方案
5. 持续集成设计
6. 测试策略
7. 架构实施
即下图:
![技术选型](http://architecture.phodal.com/images/tech-inception.jpg)
业务架构
---
> 技术是为了解决业务的问题而产生的。
脱离了业务,技术就没有了存在的前提。脱离了业务的架构不叫 “架构”,而叫刷流氓,又或者是画大饼。业务由于其本身拥有其特定的技术场景,往往是对技术决策影响最大的部分。
因此,开始之前让我们先了解一些业务,这里以 Growth 为例。
Growth 的价值定位是:**带你成为顶尖开发者**。
复杂一点的说明就是:_Growth_ **提供** _编程学习服务_ **使用** _Web开发路线_ **帮助** _新手 Web 程序员_ **解决** _Web 学习路径问题_。
让我们来看一下,更复杂一些的说明(电梯演讲):
\ | \
------------|-----------
对于 | 缺少 Web 体系经验的程序员
他们有 | 书籍、在线教程、论坛、技术问答、练习项目
我们的产品 | 编程学习软件 Growth
是一个 | 移动应用
它可以 | 涵盖Web开发的流程及技术栈,Web开发的学习路线、成长衡量等各方面。
但他不同于 | segmentfault、知乎
它的优势是 | 拥有完整的 Web 开发流程(知识图谱)、配套完整的电子书、提供练习及学习工具。
在原有的业务架构下,我们拥有 Growth、探索、社区、练习四个核心业务,以及用户中心的功能。
- Growth(首页),即带有详细介绍的 Web 应用的生命周期,能帮助开发者理解 Web 应用的构建流程。
- 探索,以辅助开发者了解 Web 应用方方面面的知识,如常用工具、练手项目、技能测验、读书路线等等。
- 练习,通过这些练习项目,来帮助开发者更好的掌握知识。
- 社区,一个简易的论坛。
- 用户中心,一些用户的收藏数据、应用相关的设置等等。
这就是业务上的主要架构,接下来让我们看看技术上的事务。
技术远景
---
> 远景,即想象中未来的远大景象。技术远景,即想象中未来的技术方面的远大景象。
在上一节中,我们介绍的是项目的业务远景。而作为一个技术人员,在一个项目里,我们也已经创建自己的技术远景。一来,我们可以创建出可持续演进的架构;二来,可以满足个人的技能需求。
以 Growth 为例,我的最基本的技术需求是:提升自身的能力。然后才是一个跨平台的技术设施——减少构建时间。
从 Growth 1.0、Growth 2.0 采用的 Ionic,到 Growth 3.0 采用的 React Native,它都优先采用新的技术来帮助自己成长,并使用了跨平台的移动应用开发框架。而这几个不同的版本里,也拥有其对应的不同技术问题
- Growth 1.0 主要是 Angular 1.x 的跳崖式升级,使之变成不可维护的系统。
- Growth 2.0 则是 Angular 2.x 那庞大的构建体积,带来了启动时间慢的问题。
- Growth 3.0 则是,React Native 生成的 ``index.android.bundle`` 文件有 3.1M,这个体积相当的大,以至于即使在高通的骁龙 835 处理器上,也需要 4~5 秒的打开时间。
而在 Growth 5.0 的设计构架里,考虑到 React Native 本身的不加密,其对于应用来说,存在一些安全的风险。我决定引入 Native 的计划,来从架构上说明,这个系统在某种程度上也是可以加密的。
因此,对于我而言,从技术上的期望就是:
- 使用新技术带来成长
- 让应用长期可维护
- 拥有跨平台的基础设施
- 插件化方案
方案对比
---
对于普通的应用来说,其需要**从不同的方案中选择一个合适的方案**。其选择的核心,取决于项目所依赖的关键点。如在 Growth 有两个关键点:代码复用程度、应用性能。
这个时候就需要罗列出不同系统的优缺点,并从中选择合适自己的一部分。
如下数据(**纯属个人使用体验总结,没有任何的数据基础**):
\ | 原生 | React Native | NativeScript | 混合应用
-----------|----------|--------------|---------------|------------
开发效率 | 2 | 4 | 3 | 5
跨平台程度 | 0 | 3 | 3 | 4
性能 | 5 | 4 | 4 | 2
成熟度 | 5 | 4 | 3 | 5
安全性 | 5 | 3 | 4 | 2
总计 | 17 | 18 | 17 | 18
PS:NativeScript 在安全性上比 React Native 好一点点的原因是,使用 NativeScript 的人相对少一点,所以技术成本就高一些。毕竟,macOS 和 Android 手机上也是有病毒的。
考虑到我打算结合不同的几个框架,所以这里就不需要选择了。
技术方案
---
在定下了基本的技术方案后,就差不多是时候进行架构设计了。
现今的很多应用里,也是采用多种技术栈结合的架构,如淘宝的 Android 原生 + Weex + WebView,或者支付宝(不确定有没有 Weex)。但是,可以肯定的是几乎每个大型应用,都会在应用里嵌入 WebView。WebView 毕竟是可以轻松地进行远程动态更新,也需要原生代码那样的后台更新策略。
在 Growth 3.0 里,我们选择了使用 React Native + WebView 的构建方式,其原因主要是 WebView 的生态圈比较成熟,有相当多的功能已经用 WebView 实现了。而在新版本的设计中,则系统变得稍微复杂一些:
![架构图 2](http://architecture.phodal.com/images/arche.jpg)
从设计上来说,它拥有更好的扩展性,毕竟在安全上也更容易操作。然而,从技术栈上来说,它变得更加复杂。
### Growth 技术方案
**原生部分**
系统在底层将采用原生的代码作为基础框架,而不再是 React Native 作为基础。再考虑到项目上正在实施的 Android 插件化方案,我打算在 Android 的 Native 部分使用 RePlugin 来引入一些更灵活的地特性。因此,从架构上来说,能满足个人的成长需求了。
毕竟原生 Android 有些架构还是相当有意思的:
![原生 Android 架构](http://architecture.phodal.com/images/android-architecture.jpg)
**React Native**
React Native 从代码上的变化比较大,架构设计上从代码上切分出几个不同的页面。它**可能可以**在某种程度上 Bundle 文件过大,带来的加载速度慢的问题。因而,在某种程度上,可能带来更快的启动速度。
**WebView**
总体上来说,WebView 变化不会太大。除了,可能从 React Native 的 WebView 迁移到原生部分的 WebView 之外。
持续集成设计
---
之前我们提到持续集成的时候,多数是指持续集成的实施。而今天我们谈到持续集成的时候,则是在讨论如何去设计。
### 代码策略
首先,就是代码策略,即代码管理策略。代码管理,指的就是决定采用哪种 git 工作流。会影响到代码管理的因素有:
- 上线功能。如某次发布要上线哪些功能,肯定会影响到正常的开发流程。
- 代码集成。当我们采用模块化、插件化来设计系统架构时,就需要将几个不同的的项目集成到一起。
- 代码合并。在有的项目里,人们会使用 PR 来提交代码,有的则是直接在 master 上提交,也有的采用 feature branch。
- 分支策略。什么时候,决定拉出新的分支?
- 修复 bug。当我们拉到一条新的分支时,我们要怎么去应对一个 bug 的出现呢?
对于 Growth 而言,则仍然是 master 分支,采用多个 GitHub 项目的集成方式。
### 工具箱
作为一个有经验的程序员,我们应该在设计的初期考虑到我们所需要的工具:
- 基础设施,诸如 React Native 需要的 Node.js、Android 及 Java 需要的构建工具 Gradle
- 文档工具,诸如架构决策记录工具 ADR,
- 开发工具,编写 Android 应用需要的 Android Studio、编写 React Native 的 Intellij IDEA
- 依赖库,这些工具是我们
- 持续集成,在持续集成上可以采用 Travis CI
- 应用发布,APP 仍然使用 GitHub 和 pgyer.com 来进行测试版发布。至于后台 API,是否从 GitHub、Coding 上迁出,仍然有待商榷。
这些也仍是我们在设计架构的过程中,需要考虑的一些因素。
测试策略
---
一般情况下,我们要会采用测试金字塔:
![测试金字塔](http://architecture.phodal.com/images/test-pyramid.png)
在这里,引用《全栈应用开发:精益实践》对于测试金字塔的分析:
> 从图中我们可以发现:单元测试应该要是最多的,也是最底层的。其次才是服务测试,最后才是 UI 测试。大量的单元测试可以保证我们的基础函数是正常、正确工作的。而服务测试则是一门很有学问的测试,不仅仅只在测试我们自己提供的服务,也会测试我们依赖第三方提供的服务。在测试第三方提供的服务时,这就会变成一件有意思的事了。除此还有对功能和 UI 的测试,写这些测试可以减轻测试人员的工作量——毕竟这些工作量转向了开发人员来完成。
而如果是架构混搭的应用来说,其的测试成本相当的大。因为要测试的部分是 3 + 1,即:
- 原生部分,采用原先代码的测试策略,如 JUnit
- React Native 部分,继续之前的 ``react-test-renderer`` 测试渲染、``jest`` 和 ``chai`` 测试业务逻辑
- WebView 部分,采用框架本身推荐的框架
- 组合部分,对于这部分来说,UI 上的测试会更加可靠,如在 Growth 3.0 中采用的 ``appium`` 就是一个不错的选择。
架构实施
---
最后,让我们来看看我在两个星期前,搭的一个架子,用于作技术验证功能。一共由三部分组件:
- 使用 Kotlin 编写的原生代码
- 使用 React Native 编写的 Fragment
- 使用 Ionic 编写的 WebView 应用
接下来看两个简单的代码示例:
### 创建 React Native 的 Fragement
如下是一个使用 React Native 编写的 Fragement 示例,它可以直接在原生的 Activity 上使用:
```
class ArcheReactFragment : ReactFragment() {
override val mainComponentName: String
get() = "RNArche"
private var mReactRootView: ReactRootView? = null
private var mReactInstanceManager: ReactInstanceManager? = null
@Nullable
override fun onCreateView(inflater: LayoutInflater?, group: ViewGroup?, savedInstanceState: Bundle?): ReactRootView? {
mReactRootView = ReactRootView(activity)
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(activity.application)
.setBundleAssetName("index.android.bundle")
.setJSMainModulePath("index")
.addPackage(MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build()
mReactRootView!!.startReactApplication(mReactInstanceManager, "RNArche", null)
return mReactRootView
}
}
```
除了将 React Native 切分成不同的几个子模块。对于一个 React Native 应用来说,它可以**注册多个 Component**
```
AppRegistry.registerComponent('RNArche', () => App);
AppRegistry.registerComponent('RNArche2', () => App2);
```
这样一来说,可以在一个 React Native 应用里被原生部分多次调用不同的组件。
### 简单的 WebView
对于那些不需要原生组件的组件来说,可以直接由原生应用来对 WebView 处理。从逻辑上来说,这样的性能会更好一些:
```
@SuppressLint("SetJavaScriptEnabled")
@Nullable
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater?.inflate(R.layout.fragment_webview, container, false)
mWebView = view?.findViewById(R.id.webview)
mWebView!!.loadUrl("file:///android_asset/www/index.html")
val webSettings = mWebView!!.settings
webSettings.javaScriptEnabled = true
mWebView!!.webViewClient = WebViewClient()
return view
}
```
对,就是这么简单。
结论
---
So,尝试去做这样的设计吧。
![架构设计](http://architecture.phodal.com/images/tech-inception.jpg)2017 年节点——T 型成长,持续学习2017-12-28T12:44:06+00:002017-12-28T12:45:29.712505+00:00Phodal Huanghttp://www.phodal.com/blog/author/root/http://www.phodal.com/blog/summary-2017-t-talents-continues-growth/> 有人经常问我,什么每年能做这么多东西。我的答案一直总是:不加班。
有人经常问我,什么每年能做这么多东西。我的答案一直:不加班。可不加班不一定能有时间做多少事,我每年做这么多东西,都是拜我们家 @花仲马 的加班所赐。
每次写年终总结的时候,总觉得我是在记录我今年做了多少事,又得是比多少人多做了一些东西。可能与去年一比较,总觉得没有特别突出的地方。今年做的很多事情,在去年也都做了;今年翻译了本书,去年也翻译了本书;今年写了本书,去年也写了一本书;今年写了很多软件,去年也是如此。大抵,还是在积累知识期,还没到一个爆发期。
这一年,发生了很多事情,35 岁的程序员在网上成为了一个门槛。早先,我对这个还是蛮担心的,后来想了想吧,这到底不算是一个总是。一来,这个问题类似于,**为什么 90 后没有一个活到 35 岁一样?**二来,35 岁学什么东西都不晚。
慢慢的去思考,不断成长的强烈的思绪,便同泉水一样不断涌现出来。是的,学习,不断地学习,才能走一步是一步。而年轻人,就是应当去学习,要不就会被 AI 淘汰了。上一辈、上上一辈,不识字的家长们,还学会了用微信抢红包呢。
编程
---
程序员嘛,代码就是日常生活的一部分。在一年里,编程上得益于对项目技术的技术栈升级——将 Cordova 嵌入到 React Native,做了一些超越前端的事件。如,使用 Java、Objective-C 编写 Cordova,随后又重写成了 React Native 插件。年底,又工作在原生 Android 的项目上,成为了一名 **XML 程序员**。想来,作为这个 “全栈工程师”,我还是蛮称职的嘛。然而,这个 “悲伤” 的故事告诉了我们一个真理,如果一个前端程序员,会 Java、会 PHP,可能会有不一样的人生。
一来二去的,在 T 型的路上,跑得越来越远。业余写的代码,还是用 JavaScript、TypeScript。值得一提的是,今年我写了很多 TypeScript 代码,用起来真心比 ES6 爽。
又想方设法地推掉一些活,倒是迎来了两三个月的 “舒适期” —— 有时间做自己想做的事情,而不是学习、练习项目相关的技术栈。在舒适期里,我不是在挖坑的路上,就是在弃坑的路上。想挖的坑太多,如我的 Ideas 列表上各式各样的想法;又如 Growth,饼画得太大太厚,最近把自己埋在坑里了。一段头脑风暴结束了,总会迎来一段收敛期。
好在异想天开的轮子也越来越少,注意力渐渐地移向**日常实用工具的开发**。如 ADR、md 就是一个很好的例子,1~2 周内完成工具的开发。每次我都会使用 md 进行排版,当我使用新项目的时候,我就会使用 ADR 来做架构决策记录。除了工具,Dore 软件又指明了一个很好的方向——总结日常的开发结晶。
等等,话说回来,那一天我还想着做一个 Blockchain Markdown Editor 呢。
写作
---
写作上,这一年倒是达到了想要的几个指标。从社交上来说,微信公号上有 22k 的粉,相比 2016 番了一番,又到了我想要的数量——可以不再以涨粉而目的的写作;相似的,知乎上则有 28k 左右的粉,与 2016 相比,大概翻了一番;GitHub 也有 10k+ 了,仍然我不知道说这个有啥意思。
今年买了很多 Kindle 电子书,大概在 150 本左右,还有一些技术类的纸质书。至于这个数量嘛,我还是不说了,毕竟大部分的书我只看了目录,外加自己觉得重要的一两个章节吧。所以,请相信我,我只看了几十本书而已。看了很多书,却没有留下笔记,可明明我是有很多思考的。下一年,有空的时候,应该多写一点书评。
上半年,在写作上来看,表现倒是相当不错。一部分内容放在豆瓣上的《我的职业是前端工程师》,在上面也有 70k+ 的阅读。拿 Microsoft Word 数了一数字数,差不多有 5 万字,差不多等于一书内容的一半。原本想顺着势头,打算在知乎上出一本前端的电子书吧。可是呢,在知乎上受《全栈应用开发》一书的影响,倒是不想写了,写书累吧,收益又少,还得挨那么多与书内容无关的人生攻击。
作为一个计划在 English 世界写 Markdown 的程序员,今年,我仍继续和 Packt 出版社合作,审阅了英语原版书 《Building Modern Web Applications Using Angular》 和《Expert Angular》。和同学翻译的《Arduino 编程:实现梦想的工具和技术》,也终究是出版了。
除了上面提到的电子书,上半年还为 CSDN 写了 《基于 JavaScript 语言的快速物联网系统开发》、《物联网浪潮之下,前端工程师如何迎刃而上》。
年初,完结的 《全栈应用开发:精益实践》也在五月份出版了。虽然这本书带来的效果远不及我预期的,但是在我心目中,它相当的优秀。从定义上来说,它蛮像《代码大全》的,只是面向的是初中级 Web 开发人员,带来了一些额外的尴尬地步。
下半年嘛,就把精力放在积累知识上了——为 2018 年写 Markdown 作准备。唯一能说得上几句的,便只有《Serverless 架构应用开发指南》一本指南了。
这样一总结,想来我还是相当能写的。
可是掐指一算,今年两本书带来的稿费,加上翻译书的稿费,还不到 20000。对,我花了半年多的业余时间,收益就这么些。我还是再去多接几个广告吧,你们有啥推荐的吗?
设计
---
显然,在这一年里,我的拍照技术是有所提升的。
而除了拍照,没做出什么设计相关的东西。UI 上做的东西,如 Growth、玩点什么,可是吧,总结出来的 UI 相关的内容又不多。这一点,倒是值得我好好去反思。
这就是我不对了,明明有那么的作品,却很难让人一眼认出这就是 Phodal 的作品。先前为了解决这个问题,我在各个地方都写上 Phodal 几个大字。这种用户体验,简直 LOW 到爆了。
于是吧,在这一两周里,我想了想,是时候做出一些 UI 上的 Refresh 了。我的博客,每天都大概 500 次访问,还有玩点什么的访问量也是相关可观的。在 GitHub 上,我用 10 个手指头数了数,大概有大概 10 个每天访问量在两位数的电子书。我还有一堆项目的 README,使用了 GitHub Pages 来吸引流量。
UI Refresh 就是在告诉用户,呀,我们改版了,不信,您再看看。这个地方由 12px 变成了 14px,这里黑色的帽子,已经变成了绿色了。
比如说,创建自己的 GitHub 主题,设计一个自己的 UI 系统,一点点的颜色,每 1px 的按钮,还有各式各样的组件,还要有吊炸天的动画。不仅仅要支持 Web,适配 Desktop,适配移动端,未来还要适配 VR、AR,blablablablablabla。对,还有微信上专用的 markdown 编辑器。
可是一算访问量来说,我倒是觉得蛮划算的。看上去是工作量浩大的工作,可是我已经想好了,我要使用 fork 大法。
对我还需要想个名字,是要叫 mdUI 呢,还有 phodalUI,又或者 mdx,取个名字真难。我先去想个名字。
……过了一个小时,我已经想到名字了,继续回来写文章。
已经有了 dore 框架,do re mi fa sol si do。按两个音阶一个单词来的话,就有了 mifa、solla、sido。每个都没有人用,那我就先占坑了。
生活
---
年中,搬到小区里合租以后,每天都在见证 “中年男女人” 的生活。大多数人生活的写照,早上开车送孩子上学,晚上回家做饭。只能有意地减少写代码的时间,再尝试去提升写代码的速度。可是要再去提高,哪怕 1% 的速率,都不是一件容易的事。
- 好的精神状态,早睡一会儿,中午眯一会儿,难免也会提高一些效率
- 更快的 Google、StackOverflow 访问速度,我想你一定懂的
- 编程时选择更高效的 IDE,写 Markdown 时使用 Sublime 获得更快的速度
- 人体工程学鼠标和键盘,少痛一会儿,就能多写一会儿
- 间歇性休息,使用手环提醒自己休息一会儿(魅族手环,50 分钟),以继续下一个时间段的冲刺。
- 保持运动
- 更好的耳机,**说实话没啥关系**,我就是想听会歌。
这一些日子里,我也做了一些饭。到底是蛮烧时间的事情,六点多到家,洗米煮饭,再去超市买个菜,洗菜切菜烧菜,再吃个饭,怕是都八点多了。
进入末夏之后,我将走路的回家方式,改成了上下班 20 分钟左右 的自行车。每天早上,难免会流点汗,但是因为吸入了很多氧气,精力上倒算是不错。最近换了新项目,骑自行车的时间多了十几分钟,但是有点运动的感觉了。
在年底的时候,总算是可以为自己和 @花仲马 存钱了。三年多了,帮家里还钱不容易呢~。
对比 2016 && hello, 2018
---
去年写的 2016 总结里,但是简单地在文章里写了几个计划。
[x] 花了相当多的时间在 Social Network上。可以适当地减少在这方面的支出了
[x] 公众号缺乏一个合理的定位。最初只是帮我们家 @花仲马 引流,那么下一步呢?
[x] 缺乏一个合适的开源软件方向,这似乎是一个很大的问题,2333~~
[x] 下一年里,我应该就会变成一个『Senior Consultant』, 是不是可以靠着这个 Title 出去刷刷脸?No
问题一,目前的投入已经差不多了,应该继续关注于主要业务。
问题二,应该写一些高质量的、引发思考的文章了
问题三,基本上是日常用的工具
问题四,在这一年里,我成为了一个高级咨询师(Senior Consultant)。 Title 上带来的变化,意味着有更多的可能性。因此,这个问题在下一年可能会变成 YES。
末了,我又在文中提了几个简单的计划,就等着明年底打脸。React Native + Visual Studio Code / Monaco Editor 制作手机编辑器2017-06-04T14:38:25+00:002017-06-04T15:04:12.085697+00:00Phodal Huanghttp://www.phodal.com/blog/author/root/http://www.phodal.com/blog/react-native-visual-studo-code-monaco-editor-build-mobile-editor/因为想为 Growth 3.0 (GitHub:[https://github.com/phodal/growth-ng](https://github.com/phodal/growth-ng))里添加一个练习功能,便想要这样的话,就需要一个代码编辑器——是的,我又要定制一个编辑器了。能想到最简单的方案就是:基于 WebView。而,我想要大致的功能就是:
- 可以用 React Native 传递代码到 WebView 里
- 点击 React Native 上的按钮,就可以运行 WebView 里的代码
便想到了 VS Code 背后的 Monaco Editor,其架构师为大名鼎鼎的「GoF 设计模式」作者之一 Erich Gamma。
因此,我要做的无非就是:
- 集成 Monaco Editor
- 制定一个简单的代码运行机制、消息规范
- 处理一些特殊的函数,如 console.log
React Native 集成 Monaco Editor
---
这一步倒是比较简单:从官网下载一个 Demo 即可,然后按示例,配置一下就可以了:
```javascript
require.config({paths: {'vs': './vs'}});
require(['vs/editor/editor.main'], function() {
var editor = monaco.editor.create(document.getElementById('container'), {
value: [
'function x() {',
'\tconsole.log("Hello world!");',
'}'
].join('\n'),
language: 'javascript'
});
});
```
而,为了支持中文,则还需要加上几句代码:
```javascript
require.config({
'vs/nls' : {
availableLanguages: {
'*': 'zh-cn'
}
}
});
```
然后在我们的 RN 代码中,引入这个 WebView 即可:
```javascript
render = () => {
let source;
if (__DEV__) {
source = require('./GrEditor/index.html');
} else {
source = Platform.OS === 'ios' ? require('./GrEditor/index.html') : { uri: 'file:///android_asset/GrEditor/index.html' };
}
return (
<webview =="" ref="{(webview)"> {
this.webview = webview;
EditorWebViewServices.setWebView(webview);
}}
startInLoadingState
source={source}
onMessage={this.handleMessage}
automaticallyAdjustContentInsets={false}
style={[AppStyles.container, styles.container, { height: this.state.visibleHeight }]}
/>
);
}
```
然后,我们就需要制定一个简单的代码运行机制。
RN 触发 Monaco Editor 事件
---
当我们在原生界面上点击运行时,我们只需要 postMessage 过去即可:
```javascript
static runCode() {
EditorWebViewServices.getWebView().postMessage(JSON.stringify({
action: 'runCode',
code: {},
}));
}
```
然后在 WebView 里处理对应的 Action:
```javascript
document.addEventListener('message', function (event) {
var data = JSON.parse(event.data);
if(data.action === 'runCode') {
eval(window.editor.getValue());
}
});
```
这里的 ``window.editor.getValue()`` 可以获取到 Monaco Editor 中的代码,为了方便我就暂时直接用 eval 函数了,啊哈哈哈~~。
这样一来,代码勉强算是可以工作了。
React Native 与 Monaco Editor 处理 console.log
---
在测试的过程中,我发现了 ``console.log`` 是没有地方输出的,想自己定制一个 Console.log 界面,发现还挺麻烦的。于是,就想到了用 Toast 来显示——于是,我便在 WebView 里覆盖住了系统的 console.log,改成了直接 postMessage:
```javascript
window.console.log = function(options) {
var result = {
action: 'console',
data: options,
};
window.postMessage(JSON.stringify(result));
};
```
而在 React Native 的组件里,则也是对数据进行对应的处理:
```javascript
handleMessage = (event: Object) => {
const message = JSON.parse(event.nativeEvent.data);
if (message.action === 'console') {
if (isObject(message.data)) {
Toast.show(JSON.stringify(message.data));
} else {
Toast.show(message.data.toString());
}
}
};
```
可这样,还是有个问题,我测试了一个 for 循环,结果发现只显示最后一个值。不过,我相信没有太多的用户会用它来写简单的代码。
React Native Monaco Editor 屏幕旋转
---
同理的,后来在处理屏幕也是相似的,在 RN 里监听屏幕旋转:
```javascript
orientationDidChange = () => {
EditorWebViewServices.getWebView().postMessage(JSON.stringify({
action: 'resize',
}));
};
```
然后在 WebView 里处理:
```javascript
document.addEventListener('message', function (event) {
var data = JSON.parse(event.data);
if(data.action === 'runCode') {
eval(window.editor.getValue());
}
if(data.action === 'resize') {
window.editor.layout();
}
});
```
周末就这么过去了,有人要来一起填坑吗?
</webview>2016年节点——增长的一年:不只编程2016-12-22T14:15:33+00:002016-12-22T14:15:41.044289+00:00Phodal Huanghttp://www.phodal.com/blog/author/root/http://www.phodal.com/blog/summary-2016-growth-year-notolny-programming/
时间过得很快很短,十二个月前在准备回南方的机票;八个月前在西安忍受着雾霾;四个月前在陪 @花仲马 吐槽桂林山水;今天我在这里,码下了这一行行的字。
在最近的一年里,有一个明显的变化是:进步不再那么明显。虽然这是一个不可避免,但是也找不到合适的突破点。这也意味着我拥有更多的非编程时间,我可以去探索更多的东西。
我开始关注于社交(技术型社交)、增长(技术营销),还有一些细分领域。从这个秋天开始,我开始走路回家,大概 4.5 公里左右。除了感觉更能走以外,还没有别的明显的变化——按理说,多运动应该能提高某方面的能力。
依旧的让我们继续从 **Line Of Business** 说起,即编程、写作、设计。LoB,即业务线,当我第一次听到这个名字,我就喜欢上它了——简单的来说,就是业务及收入来源。下面的这张图非常适合当前的情况:
![Line Of Business][1]
在过去的一年,编程(即工资)依旧是最主要的收入来源。不过值得让人高兴的是写作的收入,也相当于一个季度的工资收入。只是设计依旧不起色,这主要是没有时间投入造成的。在未来的一年,**是否咨询与演讲也可以转换变 LoB 的一部分**?
编程
---
在十月的那个国庆里,我停止了 GitHub 上的连击——「不要用战术上的勤奋,掩盖战略上的懒惰」。其实我只是想说,有些人应该关心一下上面的 Star 数好吗?
Growth 毫无疑问是今年编程方面的主角了:
![Growth Project][2]
当它还是 Ionic 1 时就有一千两百次左右的提交,而升级到 Ionic 2 时又重写了一遍,就有了上图中的 1964 次提交,差不多是 2016 提交量的 1/3。每一次更新 Growth 的时候,都有大量的代码修改,如下图所示:
![GitHub 2016][3]
然而这是一个面向最终的产品,而我一直想创建一个开发者日常使用的工具、框架等等。 Growth 可能有点难以达到这个目标,但是它对于大部分的新手程序员来说还是挺有帮助的——日活量接近 300 说明了这一点。
在工作上的变化不是很大,从之前西安的国外交付项目变为了深圳的国内交付项目。Title 变小了,做的事情也变少了,时间变多了,写代码的时间也变多了。原来的项目都要熟悉项目上的一切技术栈,还要负责架构的设计,现在只需要关注于混合应用。这是不是也意味着,**可以考虑在明年写一本混合应用的电子书**?
再回到一个老生常谈的问题,**没有一个代表性的开源作品**。这是去年 Annual Review,同事对我的建议:缺乏代表性作品。那么问题来了,**Growth 算是一个代表性的作品吗**?我需要有一个代表性的开源作品吗?我依旧没有想明白答案到底是:是还是不是。不过在下一年里,依然还需要有一个作品,不是吗?
写作
---
在这一年里,写作里面已经有相当多可圈可点的内容了。年初设定的公众号 10000 粉的目标,现在已经达到了 -> 目前是 12100 左右。
在微信公众号方面仍然有一个问题:**缺乏一个合理的定位**。开始运营公众号的时候,一方面是为了帮我们家 @花仲马 引粉,一方面则是普及读者——博客的大部分流量来源是 Google。
不过有一件事,我发现很奇怪:每当我秀恩爱的时候都有很多赞赏,但是干货的时候都很少有赞赏~。
写作上已经完成了第一步的**战略性转移**。年中的时候,我审阅完 Packt 出版社的《Smart IoT Projects》一书时,向编辑提出审阅前端书籍的请求。随后,我用 GitHub 和 Growth 项目证明了:写 Angular 2 和 TypeScript 的经验。于是我将审阅的方向转向了前端领域,这就意味着,我可以在**真正的第一时间**阅读到国外的前端书籍——作者在写书的时候,我就可以读到相关的内容。然后等这本书出版了,需要两三个月。再等到翻译成中文出版,估计到一年多以后了。现在正在审阅两本 Angular 2 的书,预期下个月和明年四月份会出版。
除此,**写作上正在尝试另外一个实验**。《自己动手设计物联网》最早是来源于我的毕业设计及 GitHub 上的开源电子书《教你设计物联网系统》,除此它还有一个开源的 APP。简单的总结一下这些步骤就是:精益出版 + 技术营销,而这一点特别适合 Growth 系列的内容。
Growth 最初推出的时候是一个开源的 APP,它被验证是有一定用处的。随后,推出了两本相关内容的电子书,即《Growth:全栈增长工程师指南》及《Growth:全栈增长工程师实战》。从项目的 Star 数和 APP 的用户来看,它特别适合于有一本纸质书籍。因为他在前期的市场宣传上已经不错了,同时它还有 APP 的用户在持续使用着。因此,你可能在明年看到这本书电子书——目前在写最后一章,出版合同还未签下。
这也存在一个问题是:**编写技术书籍相当的花费时间**。从长期来看,这是有益于国内的 IT 环境,并且有利于自己梳理自己的知识体系——电子书可以完成梳理,并且周期更短。但是编写技术书籍,对于**待我代码编成,娶你为妻可好** 的进度条影响比较小。
设计
---
尽管我一直想在设计上投入一些时间, 但是并没有那么多的可用时间。让我看到一点希望的是:我创建了一个项目:[Brand](https://github.com/phodal/brand),它让看到编程和设计之间的一些交集:即,用代码来生成一设计。SVG 是在这方面的一个很好突破点,它甚至让我有了**创建一个图形框架**的冲动。挖坑之前,让我再想想**有没有这方面的必要性**——需要在数学方面投入相当多的精力。
不过我计划在下一年里:**拍摄一些照片还当作公众号的题图**。同时,尝试去整理出一个自己的色彩集,又或者整理一个前端 CSS 框架。
生活
---
在这一年里,陪我们家花仲马去了桂林,完成她想要的毕业旅行。在国庆期间,我们去逛了逛张家界。
工作的时候,只要不下雨,轻轻松松地走上 8000 步,打卡如下:
并且,我发现这个距离的散步,很容易让我想好一篇推送的内容。
年初的时候,从西安搬到了深圳。从 1500 大概 60 平的房子,变成了 30 平不到 2400 的房子,让我感概这涨了四倍的房租,这就意味着没有那么多的地方可以放下书了。然而总算远离了雾霾的重灾区,在西安的期间动不动就咽喉炎,2333~。这高高在上的房价,让我有了挪屋的想法。
今年终于等到我们老家的房子装修年,只是年后又要身无分文的节奏。不过看这情况,明年就可以存下钱了,然后你们就可以准备三年后的份子钱了~~。
2017
---
下一年里,我应该就会变成一个『Senior Consultant』, 是不是可以靠着这个 Title 出去刷刷脸?No
[1]: /static/media/uploads/lob.png
[2]: /static/media/uploads/growth-commit.png
[3]: /static/media/uploads/github-2016.png程序员如何提高效率之休息2016-10-31T15:46:50.030854+00:002016-10-31T15:46:50.298865+00:00Phodal Huanghttp://www.phodal.com/blog/author/root/http://www.phodal.com/blog/how-to-improve-performance-by-better-rest/经常被问及为什么我可以做这么多的事,换句话来说也就是为什么效率这么高?过去我的答案里,要么是**手快**,要么是**不加班**。后来,我发现事情并没有这么简单,于是我便想着写几章文章整理整理。
在过去的两年里,保持了GitHub近两年的连击,存档了上百个项目,还凭借18k个star上榜“GitHub Star榜Top 100”。除此,审阅了两本物联网相关的书,编写了一本物联网相关的书,和基友一起翻译了一本硬件相关的书、一本物联网相关的书,在GitHub上写了开源的电子书。
保持高效的第一要点是,**休息**。问题是我们可以怎样休息呢?
- 睡觉
- 吃饭
- 走路
- 洗澡
- ...
这些都可以是休息。当我们讨论休息的时候,并不是指在睡觉。只要不是在忙与当前编码相关的事务,那么我们就是在休息。事实上,我们可以将“休息”这个词转变化**恢复精力**——这才是高效的第一要点。
### 休息时间
先让我们来看看在一天里,我们有多少时间是在休息的?
- 睡觉,这是最基本的
- 吃饭,一天三次。吃饭还得排队,又是一个多好的时间。如果你加班的话,那么你可能就是四次了。
- 上下班时间。如果你离公司很近,那么你可以在下班的时候去逛逛。
- 午休,运气好的话,你还可以在桌上趴会。
- 喝水、上厕所等等。
让我们来计算一下,大致时间花费:
- 睡觉,7~8个小时
- 吃饭,3 * 15分钟左右 = 45分钟
- 上下班时间,0.5小时 * 2 = 1小时
- 午休,0.5~1小时
- 喝水、上厕所,一天加起来也不会超过0.5小时吧。
这样算下来,一天有一半的时间都可以是休息时间。如果真的可以这样的话,那么我想你不会遇到效率的问题了~~。
#### 我的作息
之前在西安时,我作息差不多是这样的:
- 早上七点钟起床,刷牙洗漱,然后刷GitHub,八点出门坐车。
- 中午十二点半吃完饭,休息半个小时左右,刷刷GitHub,或者在翻译书。
- 下午六点下班,早期坐公交回到家里,吃完饭会先睡一觉。因为是开着灯睡的,大概就十分钟左右。后来,坐上“小猪巴士”,直接在车上**睡一觉**。
- 晚上,八点半左右才会开始写代码,十一点半上床睡觉——99%的时间是不熬夜的。
熬夜,对于我来说基本是百害而无一益,很容易影响第二天的体能和思维。因此从某种程度上来说,可以保证我有足够的精力。
而到了深圳后,主要的变化就是下班后,变成了六点走回家——50分钟左右,主要目的就是改善体能。由于这个季节,深圳的温度比西安高,回到住的地方睡不着~~,还在培养中。
并且在晚上时,有了更多的改变:
- 忙时,十一点合上电脑、手机静音,拿起Kindle或者纸质书阅读,或者白纸装逼。
- 闲时,十点便开始看书了。
毕竟,对于像我这样内向性格的人来说,独处才能恢复精力。对于外向性能的人来说,可能出去找几个朋友High一下就能恢复精力。
### 有节奏的休息
当你发现你养成习惯后,你就很容易进入状态。比如我在10点时,很容易就可以进入写作状态。当我按时11点半睡觉,我就可以很快进入状态,这些都是习惯造就的。
#### 按时睡觉
小时候,我们都是9点钟上传睡觉的,5,6点多起床。。。然后去叫叫隔壁的大哥哥,大姐姐出去玩。
长大了,我们都是11点钟上传睡觉的,然后7,8点起床。。。然后被隔壁的小屁孩叫醒。
从整体上来,熬夜会对身体和精神产生相对比较大的影响。如果你对**星期一综合症**或者**假期综合症**有所了解的话,那么你就会知道,只是因为你改变了习惯。
当然,如果你已经习惯了长期熬夜,并且没有负作用,那么你还是相当不错的~~。
这让我想到了猫~~,所以猫白天根本不理你了~~。
#### 番茄工作法
番茄工作法对于我来说,不是那么管用——天生喜欢多动,并且每天我的事务比较单一,就是编码。之所以会出现在这里,是因为它对健康有益。
我正式采用番茄工作法的原因是,在客户现场工作时,影响到颈椎了,加之我在改善尺神经卡压的影响。
这一点特别适合在工作上用,每工作25分钟,就可以休息5分钟。
所以,请使用番茄工作法作为合理的休息理由吧~~。对自己狠一点,就是对资本家好一点——除非你是资本家。
#### 碎片时间 -> 玩吧
碎片时间就适合刷刷朋友圈、逛逛微博、看看美女,看书什么的一点都不适合。
碎片时间根本不适合学习!
碎片时间根本不适合学习!
碎片时间根本不适合学习!
学习需要有高度集中的时间,你才能集中精力学习。
对了,如果你没有女朋友的话,那么你应该趁这个时间找人多聊聊天天。
#### 适当的有氧运动
> 每天应该适当做点有氧运动,如果没有女朋友的话,那么你应该出去跑步、散步啊。
只所以强调适当是因为,大量地运动不仅需要占用了你相当多的运动时间,你仍然需要相当多的时间来恢复。
而有氧运动并不仅仅局限于传统意义上的运动:跑步、打球,还可以是拖拖地。
如我最近在家里练习羽毛球颠球——转移眼睛的注意力,也算是适当的有氧运动。遗憾的是,不能在工作的地方练习。
### 小结
> 最近软件行来的的用人趋势是把人当成富士康工人用。
要成为一个大牛,就需要准备一场长期的战斗,培养自己的状态。而不是在华为干个十几年出来了,再用这十几年赚的钱去买健康,一不小心挂了怎么办?
要知道,你已经错过进入大公司最好的时机了——现在进去只能成为新一代的**富士康工人**。**你对外所说的每一句话,每一张截图,将成为你被Fire的证据。**
Growth的一个月——1.0版本接近完成2016-01-31T06:01:05+00:002016-01-31T06:01:48.660130+00:00Phodal Huanghttp://www.phodal.com/blog/author/root/http://www.phodal.com/blog/growth-one-month/Blabla,已经进入了假期模式。已会进入小规模的不活跃模式,你懂的。不过在进入不活跃模式之前,还是可以有大量的修改的。
Growth 1.0开发路线
---
在的1.0 Release的里,我大致规划了以下的内容:
1. Web七日谈: Todo事项、书单推荐、 文章列表、 工具推荐
2. 版本: WP版、 Android版、 Web版、 Electron 桌面版、iOS版本(审核中。。)
3. 附加功能:解决方案、技能测验、问题收集和展示
4. 技能树:GET技能、生成技能树、意见和建议、成就系统
5. 社区: 创建社区、用户登录、用户分享、回帖@功能
现在,除了iOS版本还在审核中,基本上已经完成了我想要的功能。
Growth,一个月的成果
---
在这一个月里,一共Release了36次,现在的最新版本是0.9.5。
CLOC工具的统计了代码行数:
Language | files | blank | comment | code
-------------------|--------------------|---------------|---------------|-----------
Javascript | 46 | 515 | 262 | 5467
HTML | 70 | 138 | 25 | 1728
JSON | 13 | 0 |0 | 537
现在的JS代码的行数是5467,HTML的行数有1728,JSON有537,外加1338行的CSS。
并且,APP的数据表明:
1. 在Fir.im上,一共累积了2863次下载。
2. 在Google Analytics上一共累积了2,151个用户。
3. 日活跃的Android用户近百。
4. Android方面:小米应用商店已经统计了640次下载(含更新)、豌豆荚统计到了463人安装、360统计到了133个下载。
5. Windows Phone方面: 统计到了8个下载。
数据同时已表明有大量的用户已经删除了程序,但是无从得知原因。与此同时,有一些数据并没有统计到。一份代码构建移动、桌面、Web全平台应用2016-01-26T14:24:10+00:002016-01-30T14:24:29.176644+00:00Phodal Huanghttp://www.phodal.com/blog/author/root/http://www.phodal.com/blog/build-full-platform-application/Web本身就是跨平台的,这意味着这中间存在着无限的可能性。
我是一名Web Developer,对于我来能用Web开发的事情就用Web来完成就好了——不需要编译,不需要等它编译完。我想到哪我就可以写到哪,我改到哪我就可以发生哪发生了变化。
最近我在写Growth——一个帮助开发人员成长的应用,在近一个月的业余时间里,完成了这个应用的:
- 移动应用版:Android、Windows Phone、iOS(等账号和上线)
- Web版
- 桌面版:Mac OS、Windows、GNU/Linux
截图合并如下:
![growth-full-platforms.png](/static/media/uploads/growth-full-platforms.jpg)
而更重要的是它们使用了同一份代码——除了对特定设备进行一些处理就没有其他修改。相信全栈的你已经看出来了:
Web = Chrome + Angular.js + Ionic
Desktop = Electron + Angular.js + Ionic
Mobile = Cordova + Angular.js + Ionic
除了前面的WebView不一样,后面都是Angular.js + Ionic。
##从Web到混合应用,再到桌面应用
在最打开的时候它只是一个单纯的混合应用,我想总结一下我的学习经验,分享一下学习的心得,如:
- 完整的Web开发,运维,部署,维护介绍
- 如何写好代码——重构、测试、模式
- 遗留代码、遗留系统的形成
- 不同阶段所需的技能
- 书籍推荐
- 技术栈推荐
- Web应用解决方案
接着我用Ionic创建了这个应用,这是一个再普通不过的过程。在这个过程里,我一直使用Chrome在调度我的代码。因为我是Android用户,我有Google Play的账号,便发布了Android版本。这时候遇到了一个问题,我并没有Apple Developer账号(现在在申请ing。。),而主要的用户对象程序员,这是一群**不土**的土豪。
![iPHONE](/static/media/uploads/iphone.jpg)
偶然间我才想到,我只要上传Web版本的代码就可以暂时性实现这个需求了。接着找了个AWS S3的插件,直接上传到了AWS S3上托管成静态文件服务。
几天前在Github上收到一个issue——关于创造桌面版, 我便想着这也是可能的,我只需要写一个启动脚本和编译脚本即可。
所以,最后我们的流程图就如下所示:
![Growth Arch](/static/media/uploads/growth-arch.png)
除了显示到VR设备上,好像什么也不缺了。并且在我之前的文章《[Oculus + Node.js + Three.js 打造VR世界](https://github.com/phodal/oculus-nodejs-threejs-example)》,也展示了Web在VR世界的可能性。
在这实现期间有几个点可以分享一下:
1. 响应式设计
2. 平台/设备特定代码
##响应式设计
响应式设计可以主要依赖于Media Query,而响应式设计主要要追随的一点是不同的设备不同的显示,如:
![full-platforms.jpg](/static/media/uploads/full-platforms.jpg)
这也意味着,我们需要对不同的设备进行一些处理,如在大的屏幕下,我们需要展示菜单:
![gnu-linux.png](/static/media/uploads/gnu-linux.jpg)
而这可以依赖于Ionic的**expose-aside-when="large"**,而并非所有的情形都是这么简单的。如我最近遇到的问题就是图片缩放的问题,之前的图片针对的都是手机版——经过了一定的缩放。
这时在桌面应用上就会出现问题,就需要限定大小等等。
而这个问题相比于平台特定问题则更容易解决。
##平台特定代码
对于特定平台才有的问题就不是一件容易解决的事,分享一下:
###存储
我遇到的第一个问题是**数据存储**的问题。最开始的时候,我只需要开始混合应用。因此我可以用**Preferences**、或者**SQLite**来存储数据。
后来,我扩展到了Web版,我只好用LocalStoarge。于是,我就开始抽象出一个**$storageServices**来做相应的事。接着遇到一系列的问题,我舍弃了原有的方案,直接使用LocalStoarge。
###数据分析
为了开发方便,我使用Google Analytics来分析用户的行为——毕竟数据对我来说也不是特别重要,只要可以看到有人使用就可以了。
这时候遇到的一个问题是,我不需要记录Web用户的行为,但是我希望可以看到有这样的请求发出。于是对于Web用户来说,只需要:
```js
trackView: function (view) {
console.log(view);
}
```
而对于手机用户则是:
```js
trackView: function (view) {
$window.analytics.startTrackerWithId('UA-71907748-1');
$window.analytics.trackView(view)
}
```
这样在我调试的时候我只需要打个Log,在产品环境时就会Track。
###更新
同样的,对于Android用户来说,他们可以选择自行下载更新,所以我需要针对Android用户有一个自动更新:
```
var isAndroid = ionic.Platform.isAndroid();
if(isAndroid) {
$updateServices.check('main');
}
```
###桌面应用
对于桌面应用来说也会有类似的问题,我遇到的第一个问题是Electron默认开启了AMD。于是,直接删之:
```html
<script>
//remove module for electron
if(typeof module !== 'undefined' && module && module.exports){
delete module;
}
</script>
```
类似的问题还有许多,不过由于应用内容的限制,这些问题就没有那么严重了。
如果有一天,我有钱开放这个应用的应用号,那么我就会再次献上这个图:
![六边形架构](/static/media/uploads/hexoarch.png)
##未来
我就开始思索这个问题,未来的趋势是合并到一起,而这一个趋势在现在就已经是完成时了。
那么未来呢?你觉得会是怎样的?