竹磬网-邵珠庆の日记 生命只有一次,你可以用它来做些更多伟大的事情–Make the world a little better and easier


282月/181

【第三方工具】Gogs使用详解

发布在 邵珠庆

https://gogs.io

Gogs使用介绍

Gogs是一款类似Github(国内有码市)的开源文件/代码管理系统(基于Git)

目前功能基本介绍
远程代码仓库管理
代码仓库权限分配、管理
团队管理
代码审查

(1)注册

自动草稿


(2)基本功能介绍

主面板说明

自动草稿


图中1表示自己个人账户下的仓库(所有权属于自己)
图中2表示自己参与的仓库(所有权不属于自己)

注意
自己个人账户下的仓库一般为自己创建,或者其他仓库所有者转让仓库。自己对该仓库具有全部权限(写入/删除文件、增加成员、删除成员、合并分之、审核分之)


新建仓库

自动草稿


在主面板中点击我的仓库右侧的” ”按钮后进入新建仓库页面,在此页面中我们需哟啊输入仓库的基本描述,并设置可见属性.
注意
在创建仓库按钮的上方有一个复选框“使用选定文件和模板初始化仓库”。
这里如果不选,则会生成一个空仓库,我们需要在本地生成一个仓库(或者原有仓库),然后将本地仓库的远程仓库地址设置成我们在Gogs中新建的仓库地址。


仓库使用基介绍

自动草稿


图中1仓库中的文件管理页面
图中2仓库的工单管理页面
图中3仓库的合并请求管理(代码审查、合并)
图中4查看代码的分支
图中5在浏览器中上传和下载文件(不依赖Git)
图中6当前仓库的远程地址(将其拷贝下来,将本地的对应仓库的origin地址设置)
图中7当前仓库的文件阅览


基于浏览器进行文件上传下载

自动草稿
可以直接在浏览器中进行文件上传


自动草稿
可以直接在浏览器查看对应文档,或者下载文档


(4)组织管理

Git魅力不仅仅体现在对代码的管理,还有有效的管理团队合作上

组织管理介绍

Gogs也专门提供了组织管理功能(组织可以代表一个公司,可以在组织下建立仓库、添加组织成员,然后通过创建和设置团队,将组织名下的仓库分别授权给不同的成员)


自动草稿
图中点击”我的组织”后面的“+”号可以新建组织


自动草稿


图中1显示当前组织下的仓库,点击创建新仓库可以添加新的组织
图中2显示当前组织中的成员,可以点击邀请其他人,添加新的成员
图中3显示当前组织下设置的团队(每个团对可以分别添加组织下的不同仓库和不同成员,并设置该团队权限(写入、阅读))


自动草稿


图中1显示该团队有4名成员
图中2显示该团队拥有当前组织的2个仓库的权限
图中3显示该团队对yo拥有的2个仓库具有读取和写入的权限

212月/180

【公众号】说说技术总监三板斧(十年肺腑之言)

发布在 邵珠庆

技术人员职业发展路线图,按照管理路线和技术路线区分。在国外管理路线和技术路线的职位会按照IT Manager和TechLead去区分,但在国内其实是没有纯粹的管理路线,管理岗位中一定有具体技术工作的要求。今天我说说对“技术总监”岗位职能要求的理解。

自动草稿

我理解技术总监的权责范畴应该包括技术性工作和管理性工作,管理性工作又分为人员管理(即团队管理)和项目管理。在技术型工作中,我认为更多考验的是一个技术管理者的技术深度和广度,而管理性工作中,更多考验的是一个技术管理者对于复杂人和事的协调能力。

一.技术性工作

对于一位优秀的技术人员而言,应该具备几种技术能力,包括:关键性技术能力、架构设计能力、工程管理能力;而一位技术管理者首先应该是一名优秀的技术人员,必须能在这三种技术能力之间游刃有余。

首先,说说关键性技术能力。

你也可以把它理解为技术难点的攻克。我曾看到过朋友圈包括饿了么CTO张雪峰、钉钉CTO一粟等,在团队面前现场coding演示某些难啃骨头的解决场景。不要求技术管理者写代码,但是在某些风险性大的技术场景里,技术管理者必须能亲自上阵,以免团队成员解决不了“甩锅”的时候可以接得起来。而且了解团队的代码情况,融入团队的代码编写,也方便对系统架构的掌控。另外,作为示范代码,能够让管理者在团队中更好的立威。

其次,讲一下架构设计能力。

我们在说到架构设计的时候,一般会提到“技术架构”和“业务架构”,脱离业务架构的技术架构一定不会成功。这就要求技术管理者对业务有良好的理解能力。而且架构的设计不仅仅是指能画架构图,能写架构文档,能把热门技术堆砌到图纸上;一个没在工地上跑过的建筑设计师一定不会造出好的大楼。反之,一个不做架构设计就想写出好系统的技术人员不是天才就是傻子。架构的设计要更好的考虑运行效率、业务的可拓展性/伸缩性,特殊场景的分模块管理等;如果做不到这些,系统将随业务的进展越来越冗余,最终将为如何“解耦”操碎心,“重构”往往就在这样的场景下被提出来,这其实是对系统和业务的具有伤害性的选择。

所以作为技术总监,必须要有大的视野去组织模块和架构,避免早期的设计缺陷造成痛苦不堪的晚期“重构”。

最后,说一下工程管理能力。

很多人对“工程管理能力”感到陌生,如果我把这块分开说为“性能”、“运维”和“效率”大家就好理解了。我们更多的认为工程管理能力关系到稳定性和效率上。小团队当中,工程管理能力往往价值体现不大,但当遇到一个大团队的时候,大团队的运转稳定性和效率就会成为突出问题。这里面主要包括持续性优化的能力和工具化使用的能力。并且需要较多的靠近流程管理和业务理解,有比较多的细小和琐碎事情。我见过很多技术管理者开发出身,但是晋升到管理者的岗位后,不得不去了解运维之类的事情。这些都属于工程管理能力的范畴。

二.团队管理工作,即人员管理

很多技术人员都很厌恶管理工作,让一个常年跟没有脾气和情绪的机器打交道的技术人员,去应付心思千万的人员管理,听上去确实很有挑战。但你要知道,管理的目标是实现组织目标,最重要的是制定管理标准、贯彻执行和校验结果。而这些也并非非要管理者亲力亲为,我们在组织的构建中强调的搭班子,就可以安排一些在这方面擅长的人以“副总监”甚至是“项目经理”“助理”的职位存在。

我觉得一个技术总监要分出30%-40%的精力在团队的管理工作上,主要包括这些方面:

第一,绩效考核

关于技术人员的KPI一直是一个千古难题,并且热度不减。难就难在技术人员工作的质量难以量化,并且受不可控因素的影响太多。我认为给技术人员的绩效指标达到两个目的即可,一个是量化可量化的东西,一个是鼓励他的积极性。

所谓量化可量化的东西,通常我们会认为是指在时间进度上量化或者bug数量、项目数量等;但其实也可以将能保证“质量”的因素模块化,分模块量化,当然这个要求比较高,因为所谓保证质量的模块,是需要技术总监确定至少是建议性,而不是丢给技术人员自行设置,比如设置必须要完成的单元测试指标、质量监控指标等。

很多人会问需不需要在技术人员的考核指标中设置业务指标,我认为在业务相对稳定的情况下是有一定可行性的,可以帮助技术人员更好的理解大团队的目标,知道在业务环节中技术价值的体现,更好的发挥主动能动性。

第二:组织结构设计和人员招募

我认为组织结构设计更好的关乎团队的效率和能力发挥,包括岗位的增删减,扁平化结构还是梯度化结构,什么样的人安插在什么样的岗位上,这也是管理者应该懂得一门大课程。

而招聘上,我只想说,对于技术总监而言抓重点岗位,普通岗位的招聘可以由经理去进行,但不要小觑招聘,寻找团队平均能力以上的人是一个团队走的远的基础。

第三,阶梯人员的培养。

我比较在乎这点,就像我并不认为一个人的成长是顺其自然,我认为每个人的成长中都是受到重要的人和事的影响的。环境对于一个人的成长非常重要,要尽可能的去创造可持续成长的环境。包括:

1.code review,我认为有必要性;

2. 技术团队内部技术方案的评审,最好的学习往往源于把手里的工作做好;

3. 外部的学习和讲座,最怕坐井观天,最后被时代抛弃,不要抱着工作不放,要想象一下未来的世界和你的位置。

第四、跨部门的沟通协调。

对于技术总监而言,除了处理部门内的事情,部门外的事情也需要一定的协调沟通,但是我并不建议多花时间在外部的会议和沟通上,更多的沟通是跟随项目走,由项目负责人去跟进和反馈即可。你只需要协调那些别人要不来的资源,当然你能要的来,大部分原因是因为你在公司的威信你曾给过别人的帮助。

三.项目管理,即对事的管理

很多公司会设立有项目经理的角色,这块就不怎么需要技术总监来操心;但反过来讲,每一位技术人员也都身兼项目经理的角色,而技术总监一定是最大的项目负责人。有关项目的事情会比较琐碎,但完全可以按照项目负责人分配下去,技术总监需要的是指定负责人、过问项目计划和进度,另外就是在项目推进遇到阻力的时候,去解决问题。主要包括这两方面:

第一,项目进度

1. 项目评审,确定项目计划;

2. 检查进度,进度延迟预警

3. 项目验收和总结

第二,资源协调

1. 人员协调,包括项目组人员以及编外人员的支持

2. IT设施协调,包括硬件、软件系统等,公司内资源还有公司外资源

 一点感悟

有一种说法,领导就是要拿别人拿不到的资源,做别人做不了的决定,承担别人承担不了的责任。

但是,我想说技术管理者难度更胜一层,技术管理者是要先有专业性,再来领导力,是需要像医者一样的仁心仁术,而不是简单粗暴的工厂管理。

我也不认同很多人认为随着时间的增长,技术人终将成为技术管理者,否则何来的“中年危机”,不是时间的累积就能得到质的变化。我身边也有很多技术管理者经常感叹:“感觉自己做到技术总监就到头了,未来乏力。”只想说,从技术能力的成长,到复杂事物管理能力的成长,再到视野和决策能力的成长,这才是一个技术人员,从程序员到中层管理者(技术总监)再到高层管理者(CTO)的能力成长过程。

如果你觉得乏力,或许应该多出来看看,毕竟有些东西是靠钻研出来的,有些东西是靠多行路、多交流得出来的,比如情商和视野,见闻的东西多了就知道该如何处理了。

72月/180

大型互联网架构演化

发布在 邵珠庆

前言

一个成熟的大型网站(如淘宝、京东等)的系统架构并不是开始设计就具备完整的高性能、高可用、安全等特性,它总是随着用户量的增加,业务功能的扩展逐渐演变完善的,在这个过程中,开发模式、技术架构、设计思想也发生了很大的变化,就连技术人员也从几个人发展到一个部门甚至一条产品线。所以成熟的系统架构是随业务扩展而完善出来的,并不是一蹴而就;不同业务特征的系统,会有各自的侧重点,例如淘宝,要解决海量的商品信息的搜索、下单、支付,例如腾讯,要解决数亿的用户实时消息传输,百度它要处理海量的搜索请求,他们都有各自的业务特性,系统架构也有所不同。尽管如此我们也可以从这些不同的网站背景下,找出其中共用的技术,这些技术和手段可以广泛运行在大型网站系统的架构中,下面就通过介绍大型网站系统的演化过程,来认识这些技术和手段。

一、最开始的网站架构

最初的架构,应用程序、数据库、文件都部署在一台服务器上,如图:

自动草稿

二、应用、数据、文件分离

随着业务的扩展,一台服务器已经不能满足性能需求,故将应用程序、数据库、文件各自部署在独立的服务器上,并且根据服务器的用途配置不同的硬件,达到最佳的性能效果。

自动草稿

三、利用缓存改善网站性能

在硬件优化性能的同时,同时也通过软件进行性能优化,在大部分的网站系统中,都会利用缓存技术改善系统的性能,使用缓存主要源于热点数据的存在,大部分网站访问都遵循28原则(即80%的访问请求,最终落在20%的数据上),所以我们可以对热点数据进行缓存,减少这些数据的访问路径,提高用户体验。

自动草稿

缓存实现常见的方式是本地缓存、分布式缓存。当然还有CDN、反向代理等,这个后面再讲。本地缓存,顾名思义是将数据缓存在应用服务器本地,可以存在内存中,也可以存在文件,OSCache就是常用的本地缓存组件。本地缓存的特点是速度快,但因为本地空间有限所以缓存数据量也有限。分布式缓存的特点是,可以缓存海量的数据,并且扩展非常容易,在门户类网站中常常被使用,速度按理没有本地缓存快,常用的分布式缓存是Memcached、Redis。

四、使用集群改善应用服务器性能

应用服务器作为网站的入口,会承担大量的请求,我们往往通过应用服务器集群来分担请求数。应用服务器前面部署负载均衡服务器调度用户请求,根据分发策略将请求分发到多个应用服务器节点。

自动草稿

常用的负载均衡技术硬件的有F5,价格比较贵,软件的有LVS、Nginx、HAProxy。LVS是四层负载均衡,根据目标地址和端口选择内部服务器,Nginx是七层负载均衡和HAProxy支持四层、七层负载均衡,可以根据报文内容选择内部服务器,因此LVS分发路径优于Nginx和HAProxy,性能要高些,而Nginx和HAProxy则更具配置性,如可以用来做动静分离(根据请求报文特征,选择静态资源服务器还是应用服务器)。

五、数据库读写分离和分库分表

随着用户量的增加,数据库成为最大的瓶颈,改善数据库性能常用的手段是进行读写分离以及分表,读写分离顾名思义就是将数据库分为读库和写库,通过主备功能实现数据同步。分库分表则分为水平切分和垂直切分,水平切换则是对一个数据库特大的表进行拆分,例如用户表。垂直切分则是根据业务不同来切换,如用户业务、商品业务相关的表放在不同的数据库中。

自动草稿

六、使用CDN和反向代理提高网站性能

假如我们的服务器都部署在成都的机房,对于四川的用户来说访问是较快的,而对于北京的用户访问是较慢的,这是由于四川和北京分别属于电信和联通的不同发达地区,北京用户访问需要通过互联路由器经过较长的路径才能访问到成都的服务器,返回路径也一样,所以数据传输时间比较长。对于这种情况,常常使用CDN解决,CDN将数据内容缓存到运营商的机房,用户访问时先从最近的运营商获取数据,这样大大减少了网络访问的路径。比较专业的CDN运营商有蓝汛、网宿。

而反向代理,则是部署在网站的机房,当用户请求达到时首先访问反向代理服务器,反向代理服务器将缓存的数据返回给用户,如果没有没有缓存数据才会继续走应用服务器获取,也减少了获取数据的成本。反向代理有Squid,Nginx。

自动草稿

七、使用分布式文件系统

用户一天天增加,业务量越来越大,产生的文件越来越多,单台的文件服务器已经不能满足需求。需要分布式的文件系统支撑。常用的分布式文件系统有NFS。

自动草稿

八、使用NoSql和搜索引擎

对于海量数据的查询,我们使用nosql数据库加上搜索引擎可以达到更好的性能。并不是所有的数据都要放在关系型数据中。常用的NOSQL有mongodb和redis,搜索引擎有lucene。

自动草稿

九、将应用服务器进行业务拆分

随着业务进一步扩展,应用程序变得非常臃肿,这时我们需要将应用程序进行业务拆分,如百度分为新闻、网页、图片等业务。每个业务应用负责相对独立的业务运作。业务之间通过消息进行通信或者同享数据库来实现。

自动草稿

 

十、搭建分布式服务

这时我们发现各个业务应用都会使用到一些基本的业务服务,例如用户服务、订单服务、支付服务、安全服务,这些服务是支撑各业务应用的基本要素。我们将这些服务抽取出来利用分部式服务框架搭建分布式服务。淘宝的Dubbo是一个不错的选择。

自动草稿

小结

大型网站的架构是根据业务需求不断完善的,根据不同的业务特征会做特定的设计和考虑,本文只是讲述一个常规大型网站会涉及的一些技术和手段。

22月/180

【流程规范】规范文档:新人培养方法论

发布在 邵珠庆

Mentor的作用

新人充满了求知欲和好奇心,学习和成长的过程中容易迷失自己,从一个萝卜坑掉进另外一个萝卜坑。
导师 == 队长(跑得快,投的准,带领全队,执行战术)
经理 == 教练  (跑不动,投不准,不下场,有经验,定战术,担责任)
职责:
  • 引路人,帮助新人快速熟悉环境、融入团队,并能在团队中找准定位,充分发挥新人的价值;
  • 通常说,导师对新人的指导周期是入职到能够独立承担工作(自己就能指导要解决什么问题或者能够指导找谁解决问题);
  • 导师对新人在学徒期的产出质量负责,新人的成长及贡献归功于导师;

Mentor的要求

能力项
要求
专业能力
  • 入职时间>1年,熟悉公司文化
  • 级别 P5+
  • 打铁需要自身硬
  • 能为新人答疑解惑
正能量
  • 技术追求
  • 工作态度
  • 主人翁精神等
  • 自驱力
沟通能力
  • 能够清晰扼要的表达出问题的解决方案
  • 能够和新人保持良好的关系,顺畅的沟通
耐心
  • 新人指导需要耐心
  • 言传身教

工作指南

时间点
工作指南
目标
入职之前
  1. 确认自己有收到新人的简历
  2. 并和主管沟通新人的大体情况以及进来后的主要工作安排
了解新人背景,提前规划工作
入职当天
  1. 和主管一起等部门助理带领新人来提前安排好的座位
  2. 和主管一起和新人一起吃第一顿饭,告知附近生活相关设施
  3. 协助新人安装电脑、配置开发环境
  4. 上线第一个敏捷功能,体验到自己的价值
开发环境能跑起来
前两周
【明确目标】熟悉、学习为主,但是任务明确。新建jira task并明确每个task的目标
【日常辅导】每天在新人座位上关心1~2次进展及问题,有问题现场协助解决或者帮他找到能协助解决问题的人
【增进了解,协助融入】不定期的一起吃饭,闲聊等,了解日常生活状况,告知部门活动相关信息,输出公司愿景,部门价值观等
【每周review】每周有一次正式的 1:1 沟通,讨论上一个阶段目标的完成情况,成绩和不足,并提供提升建议,明确下一个阶段的预期目标。review内容。
掌握jira的工作流程及良好的工作习惯
掌握开发语言,了解开发框架
了解技术部的考勤、伯乐奖、部门活动、书架计划等各类制度
前一个月
从第三周开始,根据新人进展情况,每天的辅导频次可增加或减少
继续每周一次的 1:1 沟通
【月度review】请新人写一个正式的月度总结,并和他就总结内容进行一次月度的一对一沟通,全面回顾一个月的进展,成绩和不足
第四周和月度review一起进行。review内容。
掌握git工作流程及良好的工作习惯
掌握wiki的撰写方法并有wiki产出
熟悉开发语言,掌握开发框架
熟悉至少一个子系统并能修复bug,新增小feature
理解公司愿景,部门价值观
前三个月
从第二个月开始,根据新人进展情况,【每周review】频次可增加或减少
【月度review】月度review仍然继续
【季度review】这也是一次转正review。review内容。
熟悉开发框架
完全胜任一个子系统的功能增强和bug修复的工作
三个月后 两周review一次 能够独立承担负责一个系统

注意事项

注意项
内容
自信心
根据每个新人的技术基础、学习能力,安排任务难易,把握节奏;
自信心是逐步建立起来的,注意呵护,因材施教;
自驱力
注重培养新人自我驱动能力:
责任心培养;
端到端负责;
追求卓越;
质量意识;
主动思考;
沟通能力
需求沟通:和PM谈需求时,带上新人,过程中对一些点,问问新人有什么想法;
跨团队沟通:交给一些跨团队任务,
勇于试错
鼓励新人表达自己的方案,坚持自己的想法,用于尝试;
在导师可控情况下,“看着”新人踩坑;
但相似的坑,要求不要重复踩,要有总结;
实习期,把坑踩一遍;
总结分享
养成写wiki的习惯:
较大的功能模块,尽量写wiki,组内分享;
选一些技术点(java基础,mysql,sso,死锁,性能优化,搜索等)研究,技术wiki,格式要求,分享
人情味
团队建设
一起运动,桌面足球,羽毛球,跨组认识一些人;
每周团队聚餐,鼓励新人和团队成员交流;
1:1沟通
提纲准备(eg, 放手机里);
谈话正式;
表扬要具体,比如写了一个wiki;
明确待改善的地方;
导师总结
在实践过程中,导师也要不断总结,多和其他导师、leader沟通学习;

常见问题

新人常见问题:

编号
问题
入职时间
解决方法
备注
1 环境搭建吃力,常用工具(插件,登录脚本)不清楚,口口相传 1月内 新人导航,工具导航
2 常用技术,资料,文档整理得还不太好 1月内 技术栈、知识体系
3 部署框架,测试环境,hostname设置,遇到的坑 1月内 技术栈、环境搭建
4
有的wiki比较老,更新不太及时,文档比较老
1月内 新人导航
5
项目代码,老代码(dao,APIController)没有及时清理,学习成本大
1月内 代码学习
6
陌生的技术体系和接踵而来的业务,如何适可而止的把技术面补上?
半年
技术栈、知识体系
时间管理
7
如何快速适应没有测试没有OP的开发流程?
半年 开发流程
8 知识体系不健全,导航连接需完善? 半年 技术栈、新人导航
9
开发框架,系统学习指南,知识体系梳理
1年 技术栈、新人导航
10
知识学习指南,更加具体一点:比如指定一本书,博客连接,wiki
1年 技术栈、新人导航
11
工具:插件、mysql操作,怎么倒表?常用操作?怎么服务器?怎么查日志?gc查看?
1年 工具导航
12
规范:开发规范、代码规范、上线规范、质量意识
1年 组内规范文档
13
分享:分享知识,新技术,深度控制;听不懂,跟不上问题
1年 知识分享、1v1沟通

导师常见问题:

编号
问题
问题归类
解决方法
1 怎么做培养计划? 培养计划
按照职级,目标驱动:例如,P4 -> P5
能力模型:技术能力,领导力,沟通能力,针对薄弱地方不强
2
发review周报的目的是什么?应该从哪些方面review?
review周报
3 有时比较累,什么时候放手? 节奏把控
比较费精力,规划好方案,新人只负责实施
4
这个人实在培养不出来,怎么办?
是不是只让他干脏活累活?期望太高?
分配工作的时候,应该给谁?
应该有目的,提升新人的某方面的能力?
5 新人不太“听话”?  自己觉得重要的事,新人觉得不重要?(除了技术,业务沟通、梳理,方向调研,不太热衷)
6
如何让新员工在团队中感觉到成长?
培养计划
7
如何让新员工跟上公司的节奏?
培养计划
8
如何看待新员工代码质量不高的问题?
培养方法
时间成本和质量的平衡
9
如何引导新员工快速的融入团队?
培养方法 特指工作之外的生活
10
知识学习体系,不太明晰,培养比较随意
培养计划
11
零基础同学,学习路线怎么规划?
培养计划 边学边练,给压力要结果,循序渐进
12
wiki及时维护,使用流畅
新人导航
13
业务知识,业务流程,业务词典,梳理问题
新人导航
14
技术氛围和技术提升问题,怎么能让带的同学找到方向,有计划,并且有产出?
培养计划
15
新人容易被业务拖着而缺乏积累的时间,时间怎么分配?
培养方法

问题解决办法:

1) 知识体系整理:新人导航,工具导航,wiki及时更新
2) 培养计划模板,review周报模板,整理
3) 培训分享:新人入职培训,导师上岗培训,导师互相切磋,组内分享
4) 规范整理:开发规范、代码规范、上线规范、质量意识
22月/180

【流程规范】规范文档:项目整体开发流程

发布在 邵珠庆

流程

约定

序号
环节
负责人
参与人
约定
注意点
1 初审 PM RD+QA,可选参加 产品内需达成一致
2 复审 PM RD+QA 评审->发现问题->修改->再评审
3 终审 PM RD+QA
1)到达终审的前提是各方已经就需求达成一致
2)终审如果还存在需求问题则继续复审
3)终审后不再接受需求变更
4)RD需要确认设计评审时间(尽量控制在T+5之内)。
1)需求中需要包括demo
4 设计评审 RD PM+QA
1)终审后T+3之内提供项目详细计划(包括测试计划)。
2)评审之前需要和各相关方线下达成一致。
3)设计评审时如出现重大问题则打回重审。
4)需产出设计文档、项目计划,项目相关文档沉淀在项目各个子模块中。
1)计划制定时需要注意考虑风险点和buffer
5 开发 RD PM+QA,协助
1)后台技术选型:http、mtthrift、medis、mysql
2)FE和后台交互方式:前端所有页面集中在一个工程中,后台所有服务通过API接口提供数据。
3)所有DAO层使用生成工具生成。
4)单元测试精力集中在service层,初期各模块负责人定义好需要单元测试的service范围。
5)项目初期定义交叉review分组,每周两次进行交叉review。
1)监控优先级放低
6 联调 RD PM+QA,协助
1)接口需要在设计阶段定义好。
2)接口假数据由调用方自行组织。
3)接口提供方需要先进行接口的自测。
1)联调计划安排需要考虑各方进度情况。
7 测试用例 QA PM+RD,协助
1)确认冒烟点
2)测试用例完成后需要安排用例review(PM必选,RD可选)
3)PM同学给QA开好测试task,以方便后面记录测试bug
8 测试 QA PM+RD
1)提交测试之前保证冒烟点功能通过
2)提交测试之前需要完成codereview、静态代码检查
3)提测需要发送提测邮件
4)模块完成后QA即可介入测试
5)设计同学验收样式设计是否符合预期,PM和QA一起进行功能测试
6)测试完成后QA回复提测邮件,周知测试完成
1)压力测试优先级放低
2)确认浏览器支持情况
8 上线 RD PM+QA
1)线上服务器统一收集需求统一申请
2)需要确保QA验收通过
3)上线前需要有上线计划和回滚计划
12月/180

【开发规范】规范文档:API设计规范

发布在 邵珠庆

负责API接近多年了,这些年中发现现有的API存在的问题越来越多,但很多API一旦发布后就不再能修改了,即时升级和维护是必须的。一旦API发生变化,就可能对相关的调用者带来巨大的代价,用户需要排查所有调用的代码,需要调整所有与之相关的部分,这些工作对他们来说都是额外的。如果辛辛苦苦完成这些以后,还发现了相关的bug,那对用户的打击就更大。如果API经常发生变化,用户就会失去对提供方失去信心,从而也会影响目前的业务。

但是我们为什么还要修改API呢?为了API看起来更加漂亮?为了提供更多功能?为了提供更好的性能?还是仅仅觉得到了改变了时候了?对于用户来说,他们更愿意使用一个稳定但是看起来不那么时髦的API,这并不意味着我们不再改进API了。当糟糕的API带来的维护成本越来越大时,我想就是我们去重构它的时候。

如果可以回头重新再做一遍,那么我心目中的优秀的API应该是怎么样的?

判断一个API是否优秀,并不是简单地根据第一个版本给出判断的,而是要看随着时间的推移,该API是否还能存在,是否仍旧保持得不错。槽糕的API接口各种各样,但是好的API接口对于用户来说必须满足以下几个点:

  • 易学习:有完善的文档及提供尽可能多的示例和可copy-paste的代码,像其他设计工作一样,你应该应用最小惊讶原则。
  • 易使用:没有复杂的程序、复杂的细节,易于学习;灵活的API允许按字段排序、可自定义分页、 排序和筛选等。一个完整的API意味着被期望的功能都包含在内。
  • 难误用:对详细的错误提示,有些经验的用户可以直接使用API而不需要阅读文档。

而对于开发人员来说,要求又是不一样的:

  • 易阅读:代码的编写只需要一次一次,但是当调试或者修改的时候都需要对代码进行阅读。
  • 易开发:个最小化的接口是使用尽可能少的类以及尽可能少的类成员。这样使得理解、记忆、调试以及改变API更容易。

如何做到以上几点,以下是一些总结:

1、 面向用例设计

如果一个API被广泛使用了,那么就不可能了解所有使用该API的用户。如果设计者希望能够设计出被广泛使用的API,那么必须站在用户的角度来理解如何设计API库,以及如何才能设计出这样的API库。

2、 采用良好的设计思路

在设计过程中,如果能按照下面的方式来进行设计,会让这个API生命更长久

  • 面向用例的设计,收集用户建议,把自己模拟成用户,保证API设计的易用和合理
  • 保证后续的需求可以通过扩展的形式完成
  • 第一版做尽量少的内容,由于新需求可以通过扩展的形式完成,因此尽量少做事情是抑制API设计错误的一个有效方案
  • 对外提供清晰的API和文档规范,避免用户错误的使用API,尤其是避免API(见第一节)靠后级别的API被用户知晓与误用

除此之外,下面还列出了一些具体的设计方法:

  • 方法优于属性
  • 工厂方法优于构造函数
  • 避免过多继承
  • 避免由于优化或者复用代码影响API
  • 面向接口编程
  • 扩展参数应当是便利的
  • 对组件进行合理定位,确定暴露多少接口
  • 提供扩展点

3、 避免极端的意见

在设计API的时候,一定要避免任何极端的意见,尤其是以下几点:

  • 必须漂亮(API不一定需要漂亮)
  • API必须被正确地使用(用户很难理解如何正确的使用API,API的设计者要充分考虑API被误用的情况:如果一个API可能会被误用,那么它一定会被误用)
  • 必须简单(我们总会面临复杂的需求,能两者兼顾的API是更好的API)
  • 必须高性能(性能可以通过其他手段优化,不应该影响API的设计)
  • 必须绝对兼容(尽管本文一直提到如何保证兼容,但是我们仍然要意识到,一些极少情况下会遇到的不兼容是可以容忍的)

4、 有效的API评审

API设计完成以后,需要经过周密的设计评审,评审的重点如下:

  • 用例驱动,评审前必须提供完善的使用用例,确保用例的合理性和完备性。
  • 一致性,是否与系统中其他模块的接口风格一致,是否与对称接口的设计一致。
  • 简单明了,API应该简单好理解,容易学习和使用的API才不容易被误用,给我们带来更多的麻烦。
  • API尽可能少,如果一个API可以暴露也可以不暴露,那么就不要暴露他,等到用户真正有需求的时候再将它成为一个公开接口也不迟。
  • 支持持续改进,API是否能够方便地通过扩展的方式增加功能和优化。

5、 提高API的可测试性

API需要是可测试的,测试不应依赖实现,测试充分的API,尤其是经过了严格的“兼容性整合测试”的API,更能保证在升级的过程中不出现兼容性问题。兼容性整合测试,是指一组测试用例集合,这组测试用例会站在使用者的立场上使用API。在API升级以后,再检测这组测试用例是否能完全符合预期的通过测试,尽可能的发现兼容性问题。

6、 保证API的向后兼容

对于每一个API的设计者来说,都渴望做到“向后兼容”,因为不管是现在的API用户,还是潜在的API用户,都只信任那些可兼容的API。但向后兼容有多个层次上的意义,而且不同层次的向后兼容,也意味着不同的重要性和复杂度。

7、 保持逐步改善

过去我们总希望能将现有的“不合理”的设计完全推翻,然后按照现在“美好”的思路,重新设计这个API,但是在一段时间以后,又会碰到一样的状况,需要再推翻一次。 如果我们没有有效的逐步改善的办法,依靠推翻现有设计,重新设计API只能让我们回到起点,然后重现之前的过程。 要有一套行之有效的持续改善的办法来在API兼容的同时,改善API使之更好。

8、 把握API的生命周期

每一个API都是有生命周期的,我们需要让API的生命周期更长,并且在API的生命周期结束时能让其平滑的消亡。

  • 告诉用户我们是如何设计的,避免误用,提供指导,错误的使用往往是缩短API寿命的一大杀手
  • 提供试用期,API不可能一开始就是稳定,经过试用的API才能有更强的生命力
  • 为API分级:内部使用;二次开发使用;开发或试用中;稳定;弃用API。避免API被滥用的同时,我们可以通过调整API的级别,来扩大其影响力,也能更优雅的结束一个API的生命周期。

开发API的过程其实就是一个沟通交流的过程。沟通的双方就是API用户和API设计者。

9、 一些具体的实施方案

在一个API不可避免要消亡或者改变的时候,我们应该接受并且面对这个事实,下面列举了几种保证兼容性的前提下,对API进行调整的办法:

  • 将API标记为弃用,重新建立一个新的API。如果一个API不可避免要被消亡,这是唯一的办法。
  • 为其添加额外的参数或者参数选项来实现功能添加
  • 将现有API拆成两部分,提供一个精简的核心API,过去的API通过封装核心API上实现。这通常用于解决用户需要一个代码精简的版本时。
  • 在现有的API基础上进行封装,提供一个功能更丰富的包或者类

一些好的API示例:

  1. Flickr API,这里是文档的示例,同时提供了一个非常方便的API测试工具。
  2. Mediawiki API
  3. Ebay API,这里有一个非常详尽的文档示例。

 

接口作为连通客户端与数据库进行数据流通的桥梁,起着举足轻重的作用,直接影响着程序的效率性、稳定性、可靠性以及数据的正确性、完整性。客户端注重的是界面美观,操作方便顺畅,是用户最直接的感受体验,而接口则是所有数据的提供者,是用户深层的内涵体验。

因次,设计接口在一个项目中,是非常重要的。那么我就目前的经验总结下如何合理设计接口。

一、 设计原理

1. 深入了解需求

除了设计数据库的人最了解需求外,其次就是设计接口的人了,甚至有时接口开发人员还要参与到数据库设计中。从“客户端-接口-数据库”的层次上看,接口明显扮演着承上启下的角色,一方面要明白接口要什么数据,另一方面要考虑如何从数据库获取、组织数据。所以如果不了解需求,你就无法正确抽象对象来组织数据给客户端,也无法验证数据库的数据结构能否满足需求。数据库设计者要了解需求中的数据结构,而接口则更多的要了解需求中的逻辑结构以及由此衍生出的逻辑数据结构。

2. 了解数据库结构

既然接口要明白如何从数据库获取、组织数据,就当然要了解数据库结构啦。

3. 了解客户端原型

了解原型,其实更多是为了帮助你设计接口时需要提供的数据和结构。但有时当你设计时并没有原型,所以此条并不是必须要求的。但假如设计完接口后原型出来了,我们也可以拿原型还验证接口设计是否正确、合理。

二、设计原则

1. 充分理由

不是随便一个功能就要有个接口,也不是随便一个需求就要加个接口。每新建一个接口,就要有充分的理由和考虑,即这个接口的存在是十分有意义额价值的,无意义的接口不仅增加了维护的难度,更重要是对于程序的可控性的大大降低,接口也会十分臃肿。因此我放在了第一条。

2. 职责明确

一个接口只负责一个业务功能,它与设计模式里的职责单一原则类似但却不同,因为一个业务功能里可能会包含多个操作,比如查询会员,可能除了查询会员表外还要获取该会员的其他必要信息,但不要在查询会员的同时还有修改权限等类似的其他业务功能,应该分成两个接口还做。

3. 高内聚低耦合

一个接口要包含完整的业务功能,而不同接口之间的业务关联要尽可能的小。还是查询会员的例子,有时查询会员的同时,可能该会员的相关信息要随之发生变化(如状态),如果这时一条完整的业务流水线,那么就应该在一个接口里完成,而不应再单独设立接口去操作完成。就是说一个接口不应该随着另一个变化而变化或以某几个接口为前提而存在。

4. 分析角度明确

设计接口分析的角度要统一明确。否则会造成接口结构的混乱。例如,不要一会以角色的角度设计,一会儿就要以功能的角度设计。

5. 入参格式统一

所有接口的参数格式要求及风格要统一,不要一个接口参数是逗号分隔,另一个就是数组;不要一个接口日期参数是x年x月x日风格,另一个就是x-x-x。

6. 状态及消息

提供必要的接口调用状态信息。调用是否成功?如果失败,那么失败的原因是什么。这些必要的信息必须要告诉给客户端。

7. 控制数据量

一个接口返回不应该包含过多的数据量,过多的数据量不仅处理复杂,对数据传输的压力也非常大,会导致客户端反应缓慢。过多的数据量很多时候都是接口划分不明确。

8. 禁止随意拓展参数

与第1条类似,只不过是针对参数而言了。日后拓展接口可能是难以避免的,但是不要随意就加参数,加参数一定是必要且有意义的,需求改变前首先应考虑现有接口内部维护是否能满足需求,而不要通过加个参数来方便自己实现需求的难度,因为参数的更变会直接导致客户端调用的变化,容易产生版本兼容性问题。

三、设计方法

1. 抽象业务

相比抽象对象而言,抽象业务更宏观,我觉得相对也容易一些,但抽象尺度往往不太好把握。

2. 数据格式

接口定义的数据格式必须都经过充分考虑,否则会出现数据转换失败或超出长度等错误。如果无法确定,直接设置成字符串是最合适的。

3. 有意义的命名

无论是接口还是参数,名称都应该是有意义的,让人能看明白的。

总之,接口设计是一个细致的工作,设计时也会有很多矛盾,但个人倾向于粗粒度设计方向(即内聚性更高一些),这样不仅给客户端浏览接口方便明确,维护也轻松些,这么做的缺点就是某一接口扩展时不是很灵活,但可以通过重新定义一个接口来弥补,但正如上所说,新增接口还是要三思而后行的。以上很多虽然都是理论性讲解,但牢牢记住这些,并结合实际工作,就会慢慢深刻的体会到其中的含义。即理论指导实践,实践来验证理论。

12月/180

【开发规范】规范文档:MySQL规范

发布在 邵珠庆

  • 基本规范
  • 命名规范
  • 库表设计规范
  • 索引设计规范
  • 字段设计规范
  • SQL设计规范
  • 行为规范
  • 线上操作
  • 数据变更

基本规范

(1) 使用INNODB存储引擎
(2) 表字符集使用UTF8
(3) 所有表和字段都需要添加注释
(4) 不在数据库中存储图⽚、文件等大数据
(5) 禁⽌从测试、开发环境直连线上数据库

命名规范

(1) 表名:必须使用小写字母,多词之间以”_“(下划线)分隔,表名非复数名词,禁止使用mysql保留字。
(2) 字段名:必须使用小写字母,多词之间以”_“(下划线)分隔,字段名使用名词,禁止使用mysql保留字。
(3) 索引名:普通索引以”idx_“ 加上字段名命名;
唯一索引以”uk_“加上字段名命名;
组合索引的命名须按顺序包含索引中的所有字段。如:”a,b“的组合索引,命名为”idx_a_b“,名称过长可适当采用缩写。
(4) 临时库、表名必须以temp为前缀,并以⽇日期为后缀,如:temp_img_syn_to_mdc_table
(5) 备份库、表必须以bak为后缀,并以日期为后缀,如:hotel_sm_boss_info_bak20150615
(6)名称应该清晰明了,能够准确表达事物的含义,最好可读,遵循“见名知意”的原则。

库表设计规范

(1) 一条完整的建表语句中应包含必要的字段、主键、合理的索引(综合代码中所用到的条件语句创建合理的索引)
(2) 字段应当有注释,描述该字段的用途及可能存储的内容,如枚举值则建议将该字段中使用的内容都定义出来

索引设计规范

(1) 主键准则
a、表必须有主键
b、建议使用自增id作为主键
(2) 重要的SQL必须被索引,比如:
a、UPDATE、DELETE语句的WHERE条件列
b、ORDER BY、GROUP BY、DISTINCT的字段
(3) 一般原则
a、创建复合索引时区分度较大的字段放在最前面,不在区分度小的数列上建立索引,例如“性别”
b、核⼼SQL优先考虑覆盖索引
c、避免冗余和重复索引
d、索引要尽量选择离散度比较大的字段,选择查询频率比更新频率高的字段。
e、索引字段的默认值不能为NULL,要改为其他的default或者空。NULL非常影响索引的查询效率。
f、 尽量不使用外键
g、 新建的唯一索引必须不能和主键重复
h、不使用%前导的查询,如like“%xxx”,无法使用索引;不使用反向查询,如not in / not like;无法使用索引,导致全表扫描
i、 尽量用多列联合索引代替多个单列索引
j、 能使用唯一索引就要使用唯一索引,提高查询效率

字段设计规范

(1) 尽可能不使用TEXT、BLOB类型
(2) 用DECIMAL代替FLOAT和DOUBLE存储精确浮点数
(3) 越简单越好:使用TINYINT来代替ENUM类型
(4) 如果可能的话所有字段均定义为not null
(5) 禁止在数据库中存储明文密码,把密码加密后存储
(6) 不允许使用ENUM
(7)使用TIMESTAMP存储时间. 因为TIMESTAMP使用4字节,DATETIME使用8个字节,同时TIMESTAMP具有自动赋值以及自动更新的特性.

SQL设计规范

(1)强烈建议使用INNER JOIN代替子查询。
(2) 避免在数据库中进⾏数学运算(MySQL不擅长数学运算和逻辑判断)
(3) 不要用select *,查询哪几个字段就select 这几个字段
(4) 使用in代替or,in的值不超过1000个
(5) 任何对列的数学运算操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要
尽可能将操作移至等号右边。
(6) limit分页注意效率。Limit越大,效率越低。可以改写limit,比如例子改写:
  1. select id from t limit 10000, 10; => select id from t where id > 10000 limit 10;
(7) 在SQL语句中,禁止使用前缀是%的like
(8) 不使用负向查询,如 not in/like
(9)SQL尽量简单,尽量少的包含业务逻辑,业务逻辑交给应用处理。

行为规范

1、批量导入、导出数据必须提前通知DBA协助观察;
2、批量删除更新操作,如影响条数超过1000的update、delete操作,需要联系DBA进行审查,并让DBA执行
3、线上数据回滚,申请新DB,请联系DBA;
4、不在业务高峰期批量更新、查询数据库;
5、重大项目的数据库方案选型和设计必须提前通知DBA参与