Commit e3174fb8 authored by 陈昊's avatar 陈昊

第一版规范编辑完成

parent db6ad61a
# 项目规范和要求
本文件用于规范所有项目成员的开发行为,并在一定程度上保障项目的代码质量。<br/>
本文件规定了在项目开发中,代码应该怎么写,不能怎么写,以及部分规范在什么情况下可以例外。<br/>
除了本文件中规定的所有规范以外,在部分项目中还有各自独立的规范要求和约定。在项目规范和本规范有冲突时,以具体项目规范为准。<br/>
## 基本目标
本规范期望达到的目标有以下几个
* **让项目易于维护:** 通过统一的代码规范和约定,让项目代码变得更容易阅读。让任何一个具备相关知识的开发者都能够在尽可能短的时间内上手进行基本的开发和修改。
* **控制代码质量:** 通过强制性的代码规范和约定,避免一些容易出现在开发中的影响到代码质量的问题。
* **降低部署风险:** 通过执行代码规范和约定,来降低从测试到部署的过程中出现问题的风险。
## 项目代码编写原则
每个项目参与者在进行项目开发时,都应该尽其所能的遵守以下几个原则
### 开始开发前
* **不要立即动手:** 拿到需求后不要马上进行编码。先进行思考并和产品沟通,**确保自己确实理解了需求,并对整个流程了然于胸之后,再动手**
* **先进行询问和检索:** 在进行开发之前,先了解一下想要的东西是不是已经有了类似的实现,或者干脆就不需要实现。**避免让开发变成重复造车轮**
### 开发过程中
* **随时注意自己的编码是否易读:** 尽可能的做到**每一行代码都能让人一眼看懂**,而不需要花费额外的时间去理解。
* **随时注意自己的脚本和函数是否功能单一而且明确:** 如果需要实现复杂的逻辑,就将其拆成多个简单功能来调用。**确保每个函数的功能能用一句话说清楚**
* **随时注意避免代码过度耦合:** 避免重复造车轮,最关键的就是在制造车轮的时候考虑到**其他人也可能会用到**
* **随时注意代码长度是否过长:** 如果是单个函数代码过长,考虑拆成几个子函数;如果是单个文件过长,考虑拆成多个文件;单个模块文件太多的,考虑建立一个子目录来存放文件。
### 开发完成后
* **至少完成一次代码自审:** 在代码完成之后,**必须重新审查一遍**。以便于补充注释,修改错漏,删除多余的打印输出。
* **上传之前必须进行检查:** 每次推送代码到服务器之前,先确认当前代码能否**正常**运行,确认之后才能上传。
* **每次提交都要明确的说明修改了什么:** 除了合并代码以外,在提交的时候应该明确的说明自己这次的提交修改的内容。**不要在提交的时候随意编写毫无意义的提交说明**
**以上要求可能会随时增加,请随时关注本规范的最新版本**
***
## 注释规范
规范注释是规范代码的第一步,写不好注释的人,就算个人技术能力再怎么高,也难以适应团队化的开发。
### 1、注释格式
在项目中,只允许使用以下几种注释格式之一
1. 多行注释
```js
/**
* 这是多行注释,通常用在每个文件的头部或者函数头部,也可以用在其他任何需要大段注释的地方。
* 本规范并不对多行注释的行首星号和缩进之类的细节做任何要求,但是注释仍然需要遵循基本的规范。
* 注意:以下所有注释内容都是可选的,但是一旦使用,就必须符合对应的格式要求。
* @param {string} something 这是对参数的注释,格式是:@param {参数类型} 参数名称。在本例子中就是说明了一个名字叫做something的string类型参数。在接受的参数比较复杂时,最好在之后的文本说明中追加具体说明。
* @return {object} 这是对返回结果的注释,格式是:@return {返回类型}。在本例子中就是说明了接口或函数的返回结果是一个对象。
* @author 陈昊 这是对作者的注释,通常用在单个脚本文件的头部,说明了这个脚本的函数的编写者是谁。一般除非重写,否则不要覆盖最初作者的名字。
* @version 1.0.190314 这是脚本/函数的版本号,共有三级。第一级从1开始,在单次修改(单纯的增加不算)超过1/3时建议修改第一级版本号。第二级版本从0开始,只要对脚本进行了功能性方面的修改之后,就建议修改该版本号。第三级是脚本的最后一次修改的日期,每次修改都应该修改。不建议对不是特别重要的脚本使用该注释。
* @description 这里添加具体描述。实际上一般不需要使用@description关键字,直接把说明内容写在后面就好了。
*/
```
2. 单行注释
```js
// 这是一个独立的单行注释,可以用于几乎所有需要注释的场合,单行注释要写得简单明了。如果说明内容太长的话则建议换成多行注释。
```
3. 代码后注释
```js
let tmp = null; //这是单行代码后的注释,通常用于变量说明和if分支说明。内容和单行注释一样要求精简
```
**不要把注释写在一行代码的前面或者代码的中间**
### 2、必须添加的注释
1. 除部分由其他脚本生成的脚本文件以外,在每个js文件的顶部必须有一个说明脚本功能的多行注释。多行注释至少需要说明清楚本脚本的大致功能和使用场合,并且要标注原始作者。<br/>
脚本功能注释例子如下:
```js
/**
* 压缩解压模块
* @author 陈昊
*/
```
在更旧的规范中,曾经要求在js文件顶部标注版本号。但是由于实际意义不大现在已经取消的这个要求
2. 在每个函数之前,必须要有一个单行或者多行注释来说明函数的功能。如果函数比较复杂,则需要对参数和返回进行说明。<br/>
函数注释例子如下:
```js
//用gzip压缩目标对象或字符串
function zip(raw) {
//这里是函数内容
}
```
3. 所有非函数内局部变量都必须在声明之后加上注释。只要一个声明在一个函数之外,或者在多个函数中使用,就必须加上注释。**但是当该变量是对其他脚本的引用的时候,可以不加注释**<br/>
例如:
```js
const _ = require('lodash'); //这个变量因为是对其他库和脚本的引用,可以不加注释
const curVersion = 1; //这个变量声明在某个函数之外并且在函数内被引用,必须添加注释
//检查版本是否和当前版本对应
function checkVerison(v) {
return v == curVersion;
}
```
### 3、建议添加的注释
1. 函数内声明的变量,使用次数比较多或者是变量名不够一目了然的,建议添加注释来对变量进行说明(*下例中的1类注释*
2. 接下来的数行代码用于实现一个明确功能的,建议添加注释对该段代码逻辑进行说明(*下例中的2类注释*
3. 代码中某个地方需要注意的时候,建议添加注释进行提醒(*下例中的3类注释*
4. 对于某些复杂的逻辑判断,其他开发人员可能不能一眼看懂的,建议添加注释进行说明(*下例中的4类注释*<br/>
应用示例:
```js
// 获取用户数据
async getRaw(guid) {
let keyGuid = `g:${guid}`; //GUID在redis里对应键值(1类注释)
let raw = await redis.get(keyGuid);
if (!raw) {
return null;
}
raw = JSON.parse(raw); // 写入redis的数据都是用JSON.stringify生成的,因此源数据必然是合法JSON(3类注释)
if (raw.userID < 0) { // 若数据已经失效,返回失败信息并删除原GUID数据(4类注释)
redis.del(keyGuid);
return raw;
}
// 检查用户数据版本并处理(2类注释)
if (raw.version == curVersion) {
redis.expire(keyGuid, timeLimit);
redis.expire(`u:${raw.userID}`, timeLimit);
} else if (raw.version > curVersion) {
throw new Error('用户数据版本高于当前服务器版本,请及时更新服务器');
} else {
raw = await this.createUserInfo(raw);
redis.setex(keyGuid, timeLimit, JSON.stringify(raw));
}
return raw;
};
```
### 4、不建议添加的注释
1. 尽量不要在文件头部或者代码中添加文档级别的大量注释,如果确实需要进行大量的说明。可以单独编写文档,或者在文件底部专门编写大量说明用注释。
2. 不要编写那些写了和没写一样的注释。
例如:
```js
// 把数据库查到的数据处理成以key为键值的JSON并返回
function rows2json(rows, key = 'id'){
let json = {} // 待返回的JSON(由于该函数代码太短,这个变量的作用一眼就看出来了,因此这里的注释没有实际作用)
//处理数据,将其处理成以key为键值的JSON(几乎就是把函数功能复述了一遍,这个注释也没有意义)
for(let i=0; i<rows.length; i++) { // 遍历输入的数组(这种注释显然没有任何价值)
let cur = rows[i]; //当前数组对象(无论是从代码还是变量名都可以简单的知道这个变量是啥,该注释没有意义)
json[cur[key]] = cur;
}
return json; //返回JSON(这种注释显然也没有意义)
}
```
3. 过于琐碎的注释。注释不能没有,也不宜太多,连续琐碎的功能性注释不如整合到一起放到代码块之前。
## 代码规范
### 1、严格模式
除由其他脚本生成的脚本,配置脚本和项目中固定的,不会频繁修改的文件以外,所有js脚本都**必须**使用严格模式编写。<br/>
不要轻易使用公共变量。
### 2、代码的整合和分块
1. 在代码中,应该适当的使用空行来对代码进行整合或者分块
2. 对其他脚本的引用,应该一并放到文件头部统一声明
3. 在多个函数内,或者在同一个函数内多处逻辑块内使用的变量,应该整合起来放在文件头部或者函数头部
4. 在每一块连续的代码中,代码功能应当单一明确,不宜把不同的代码逻辑混在一起交替编写。具体来说,就是如果一段代码是负责完成某个功能的,那这段代码中就不应该出现任何和该功能无关的代码
```js
// 这是一个比较好的代码整合分块例子
'use strict'
const _ = require ('lodash')
const fs = require('fs')
const crypto = require('crypto')
let var1 = '' //某个在脚本中反复使用的变量
let var2 = '' //另一个在脚本中反复使用的变量
//完成某个功能的函数
function funcA(){
let local1 = 0; //一个在函数中多处用到的变量
let local2 = 1; //另一个在函数中多处用到的变量
//实现一个功能的代码
let tmp = local1; //改变量只在这个子逻辑中使用,因此不宜放到函数顶部
local1 = local2;
local2 = tmp;
//实现另一个功能的代码
let result = []; //该变量只用在这个子逻辑中,并且在逻辑完成后立即返回,因此可以选择放在逻辑块头部或者函数头部。若其在子逻辑完成后仍可能被使用,则应放在函数头部
result.push(local1);
result.push(local2);
return result;
}
//其他函数省略
```
```js
// 这是一个不好的代码整合分块例子
'use strict'
const _ = require ('lodash')
let var1 = '' //某个在脚本中反复使用的变量
const fs = require('fs')
const crypto = require('crypto')
//完成某个功能的函数
function funcA(){
let local1 = 0;
let local2 = 1;
let tmp = local1;
local1 = local2;
let result = [];
result.push(local1);
local2 = tmp;
result.push(local2);
return result;
}
let var2 = '' //另一个在脚本中反复使用的变量
//其他函数省略
```
### 3、变量的命名规范
* 除了一些约定俗成的变量,和在极小范围(10行以内)内使用的局部变量以外,尽可能避免使用没有意义的变量名。*(约定俗称的变量如循环中的“i”,“j”,“k”。lodash用的“_”等)*
* 如果实在想不出合适的变量名而必须用拼音或其他无法直接理解的字符串来代替的,要在变量声明时加上注释
* 对于一些可能有歧义的变量名,最好加上注释。*(例如key这个变量,在某些脚本中就有可能是“关键字”或“键值”,具体根据代码逻辑是否可能产生歧义来决定是否加注释)*
* 变量名不宜过长,尽可能控制在10个字符串以内为佳。过长的变量名可以在进行精简之后添加注释来进行说明。*(虽然bannedWordList的意思比banList要准确得多,但是变量名太长会影响代码阅读效率)*
* 尽管由于历史原因,很多脚本的变量名命名规范没有得到完全统一。但是至少不要在同一个脚本中使用不同的变量命名规范。
### 4、代码长度和流程控制规范
* 单个脚本尽可能避免超过500行(含空行,不含注释),当单个脚本太长的时候,就需要考虑脚本是否可以根据子功能拆成多个子脚本
* 单个函数尽可能避免超过50行(含空行,不含注释),当单个函数太长的时候,就需要考虑是否可以把函数内部的子逻辑拆成独立的函数进行调用
* 代码尽量避免超过5级的缩进,但是JSON和数组之类的数据结构内分级不包括在内
* 尽量避免使用3层以上的嵌套循环,若循环太深,建议把内部循环做成独立函数
* 单行代码(含注释)尽可能不要超过100个字符长度(约2/3屏幕),若单行代码过长,建议拆成多行
### 5、其他开发要求
* **缩进必须规范**
* 代码中要适当的使用空格
* 函数功能尽可能单一明确,具体来说就是一个函数的功能最好一句话就能描述清楚
* 复合功能函数应该以调用其他函数为主,尽量避免在其内部有长串可以分割为单一功能的逻辑代码块
* 避免过高的耦合度,在进行脚本和函数开发的时候尽可能考虑到其他使用者
* 数据配置和实现逻辑应当分离,尽可能避免在实现逻辑中使用写死的数据
* 对于作废的大段代码,要直接删除,不要使用注释的方式来将其保留起来
## 版本管理规范
除了部分老旧项目以外,目前的新项目已经全部统一使用gitlab进行版本管理。使用git时要遵循以下要求
### 1、每次提交,必须要对本次的提交内容做出有意义的描述
每一次提交,都必须要明确的说明这次提交了哪些修改,影响了什么功能。以下的提交说明是不可接受的
* aaa *(如果确实什么都没有完成,可以这样写“XXX功能开发到途中,临时提交变更”)*
* 提交 *(可以改成“提交了关于XXX功能的修改”)*
* 改了几个bug *(可以改成“修改了XXX无法显示的bug和XXX数据错误的bug”,至少也是“修改了关于XX系统的三个bug”)*
* 增加了一些功能 *(可以改成“增加了XX功能”或者是“增加了XX相关内容”)*
### 2、在推送代码到远程库之前,必须要确保所有冲突已经解决,并且项目能够正确的运行,方可推送
始终要记住**远程库的代码就是线上要运行的代码**,因此,在确保冲突解决并且项目能正确运行之前,绝对不能把代码推送到远程库。
**由于代码推送时没有处理代码冲突导致线上服务无法启动或者出现bug的,直接扣绩效**
### 3、在处理一个需求或者对bug进行修改时,新建临时分支用于修改。不要在develop和master分支上直接进行开发
在每次处理一个任务之前,一定要记得。首先从master或者develop分支上新建一个处理当前需求的临时分支,然后在这个分支上完成你的工作以后再将其合并到develop分支。并提交master分支的和并请求。
### 4、已经完成任务的分支要记得删除,避免项目分支过多导致混乱
由于要尽可能的确保任意时候的远程库都能直接在线上运行,因此没有开发完整的功能要尽可能的避免推送到远程库。以降低线上故障的发生率。
### 5、为了确保每个项目成员能都能正确的使用分支,请先阅读以下链接的内容并照做
[git分支练习用项目](http://114.55.97.172/chenhao/git-branch-test/tree/develop)
## 发布规范
### 1、测试站的发布流程
在测试库进行测试的时候,不需要使用git进行提交。在没有代码冲突的前提下,完全可以直接使用FTP软件直接把修改过的文件直接托上去覆盖原本的文件进行测试。<br/>
为了避免git版本过于零碎,并不建议每次调试修改都提交一个版本然后用git拉去最新的到服务器上。
### 2、正式站的发布流程
正式站除了配置文件以外,不允许任何从本地拖取文件对服务器代码进行替换的行为。
正式站按以下步骤进行发布:
1. 发布数据库的修改
2. 对远程服务器的配置进行修改
3. 确保所有必要的修改已经推送到远程库
4. 登陆服务器,使用git确认当前运行中的代码版本并记录
5. 使用git从远程库拖取最新代码
6. 对最新版服务器进行启动测试
7. 确保启动测试没有异常之后,逐个重启服务
8. 若线上服务有严重问题,立即使用git恢复到第4步记录的版本并重启
\ No newline at end of file
# 项目管理办法
本办法用于规范所有项目成员的行为,控制项目风险和提升项目质量。
## 目标
本办法预期达到以下目标
1. 降低项目风险:通过相关办法,让项目成员能够有意识的约束自己的行为,进而降低整个项目的风险
2. 提高项目质量:通过相关规范,让项目成员能够编写出规范的,标准的项目代码,进而提高整个项目的质量
3. 降低运维成本:通过相关标准,让项目成员的代码风格统一,并按要求提供注释,从而使项目的维护更加简单
4. 提高开发效率:通过相关流程,让项目成员能够更有效的完成开发和测试,进而提高项目开发效率
5. 提升个人能力:通过相关指南,来让实力不足的项目成员能够自主获得能力上的提升
## 项目管理相关规范和办法
### 基本要求
所有成员**必须**严格遵守以下规范和办法
* [敏感信息管理办法](./敏感信息管理办法.md)(2019/9/5)
* [项目基本规范](./规范/README.md)(2019/9/5)
### 进阶要求
项目成员应尽量遵守以下规范
* [项目进阶规范](./规范/项目进阶规范.md)(2019/9/5)
## 操作流程
* [代码仓库操作流程](./流程/代码仓库操作流程.md)(待编辑)
* [测试流程](./流程/测试流程.md)(待编辑)
* [发布流程](./流程/发布流程.md)(待编辑)
## 指南
* [项目开发原则](./指南/项目开发原则.md)(2019/9/5)
## 最后更新
2019/9/5
\ No newline at end of file
# 项目开发原则
## 一、设计阶段
* 刨根问底:在拿到需求之后,要对需求方刨根问底,在确实理解整个需求之后才能动手
* 三思而后行:在着手开发之前,必须要花费时间把整个流程梳理一遍。明确每一步如何实现,以及中间会有什么问题之后,再动手
* 胸有成竹:在实际动手之前,必须确保自己已经对整个项目了如指掌,然后才能动手
## 二、编码阶段
* 一眼能看懂:开发的时候,注意自己代码的易读性问题,随时以第三者的角度审视自己的代码
* 一句能说清:每个函数的功能应当尽可能明确单一,做到一个函数的功能能用一句话说清楚
* 不要重复造车轮:开发的时候要尽量避免代码高度耦合,尽力做到功能性的泛用。并且记得询问是否已有类似功能
## 三、测试和调整阶段
* 先自审:完成开发以后,应该对自己的代码进行一次自审,通过自审可以避免代码不规范的问题
* 预防意外:开发者原则之一是“用户永远不会按你期望的方式去使用你的软件”,因此除了走正常操作流程意外,我们还应当考虑和测试一些不正常的操作流程
* 主动寻找漏洞:在测试的时候,应当尝试作为攻击者主动寻找产品中的漏洞进行攻击
## 四、发布及后续跟进
* 三省吾身:在产品发布以后,还应当持续跟进一段时间,主动从项目中总结经验,并思考优化和解决策略
\ No newline at end of file
# 敏感信息管理办法
## 敏感信息定义
本办法所提及的敏感信息主要是指涉及公司商业秘密的数据,包括但不限于以下内容
* 个人工作QQ的账号和密码
* 用于连接阿里云服务器的个人账号和密码
* 用于连接代码仓库的个人账号和密码
* 用于链接测试站点数据库的账号和密码
* 用于连接正式站点数据库的账号和密码
* 各个项目的项目代码
* 正式和测试站点的数据库内容
* 用户的个人信息,包括但不限于用户姓名,身份证号,手机号,住址等用户的私人信息
## 刑法相关条款
第二百一十九条 有下列侵犯商业秘密行为之一,给商业秘密的权利人造成重大损失的,处三年以下有期徒刑或者拘役,并处或者单处罚金;造成特别严重后果的,处三年以上七年以下有期徒刑,并处罚金:<br />
(一)以盗窃、利诱、胁迫或者其他不正当手段获取权利人的商业秘密的;<br />
(二)披露、使用或者允许他人使用以前项手段获取的权利人的商业秘密的;<br />
(三)违反约定或者违反权利人有关保守商业秘密的要求,披露、 使用或者允许他人使用其所掌握的商业秘密的。明知或者应知前款所列行为,获取、使用或者披露他人的商业秘密的,以侵犯商业秘密论。<br />
本条所称商业秘密,是指不为公众所知悉,能为权利人带来经济利益,具有实用性并经权利人采取保密措施的技术信息和经营信息。<br />
本条所称权利人,是指商业秘密的所有人和经商业秘密所有人许可的商业秘密使用人。<br />
## 个人账号和密码管理办法
1. 所有项目成员应妥善保管自己的个人账号和密码
2. 严禁擅自将自己的个人账号和密码透露给他人,使他人能访问其原本无法访问的敏感信息。确需权限的情况下可以由有权限的人代为操作,或是向上级申请权限
3. 测试站的数据库和redis的账号密码目前是公用的,因此可以透露给相关项目的研发成员,但是禁止透露给无关人员
4. 所有阿里云服务器的远程访问,都必须使用自己的私人账号进行
5. 更换工作电脑前,必须清除原电脑上所有和个人账号密码有关的数据
## 项目代码管理办法
1. 项目成员将会根据自己负责的内容获得对应代码仓库的访问权限
2. 严禁将项目代码以任何形式发送给无关人员,包括其他项目组的成员。确实需要的,应向上级申请授权
3. 不得向无关人员透露项目相关信息和架构等内容。这些内容包括但不限于,某个项目实现的具体功能,项目提供的具体接口,特定业务的具体逻辑等
4. 更换工作电脑前,必须清除原电脑上的项目代码,远程仓库访问密钥等内容
## 数据库数据管理办法
### 测试站数据库管理办法
1. 在不会对项目造成重大影响的前提下,对测试站的数据内容进行修改不需要特别授权,但最好提前通知一下相关人员
2. 在开发时,可以根据自己的判断在测试站数据库里新建数据表,但是必须让相关负责人知情
3. 如果需要修改现有数据表的结构,必须提前告知详细修改计划,并获得相关负责人授权
4. 严禁将测试站的数据结构和数据内容导出并透露给无关人员
### 正式站数据库管理办法
1. 助理工程师和项目工程师不允许在未经授权的情况下修改正式站数据库的任何数据
2. 负责管理后台的高级工程师可以根据产品和客服的要求,无需领导授权就对不涉及用户消费的数据进行修改,但是所有涉及用户消费的数据必须要需求方给出纸质的操作需求并有经理级以上的领导签字方可操作
3. 不允许在不经过测试的情况下直接在正式站数据库新建数据表,在正式站数据库新建数据表前必须经过测试,并提前获取相关负责人授权
4. 不允许在不经过测试的情况下修改正式站数据库的数据表结构,在正式站数据库修改数据表结构前必须经过测试,并提前获取相关负责人授权
5. 严禁将正式站的数据结构和数据内容导出并透露给无关人员
# 文档修订记录
* 2019/9/5:初版
\ No newline at end of file
# 运维规范
\ No newline at end of file
# 绩效考核规则
## 绩效计算规则
* 每月绩效满分是100分,所有人初始分数都是100分,并且每月分数不会大于100分
* 触发扣分项目时当月绩效会根据具体项目扣除相应分数
* 达成加分条件的,将会获得对应的加分,当月加分之后绩效超过100的,超出的部分可以保留至次月,每次加分至多保留3个月(例:A某月全勤并且没有被扣分,则当月其总分101分,多出1分;若A次月没有全勤,则多出的1分可以抵消A次月没有全勤被扣的1分)
## 扣分项目
### 考勤和工作态度
* 没有全勤,-1分
* 事假超过24小时(不含24小时),N=请假天数, -5 + (N-3)*-1分
* 上班睡觉,-2分/次
* 因个人工作态度问题,被其它部门投诉的,-2分/次
### 计划和进度
* 开发超出计划时间,导致无法按时测试的,N=超出计划测试天数,N*-1分
* 开发超出计划时间,并导致产品无法按时上线的,N=超出计划上线天数,N*-2分
* 没有按时汇报每日工作大于等于3次的,N=次数,(N-2)*-1分(注:全天请假的情况不需要汇报)
* 没有在限定时间内提交周计划的,-2分/次(限定时间为每周最后一个工作日和下周第一个工作日上午)
### 工作质量
* 负责的功能在上线之后出现严重影响用户使用的BUG的,N=修复BUG所用天数,N*-3分/次
* 负责的功能在上线之后出现BUG,但是没有严重影响用户使用的,N=修复BUG所有天数,N*-1分/次
* 不遵守Git管理规范,直接提交代码到禁止直接提交的分支的,-1分/次
* 不遵守tag管理规范,擅自使用tag并提交到远程库的,-1分/次
### 安全性
* 提交代码前没有删除代码中的敏感信息的,-20分/次
* 负责的代码存在可利用漏洞并且在修复之前被项目组研发成员以外的成员发现的。若是被公司内部其他部门发现,-2分/次,被公司外部发现,-5分/次
## 加分项目
* 全勤,+1分
* 对系统基础架构提出有效的优化方案,被项目负责人认可并实施的。+3~+10分/次
* 对不由自己负责的业务系统提出有效的优化方案,被项目负责人认可并实施的。+2~+5分/次
* 对由自己负责的,已经上线运行的系统,在不影响原工作计划的前提下主动进行完全重构级优化,被项目负责人认可并实施的。+1~+3分/次
* 对由自己负责的,已经上线运行的系统,在不影响原工作计划的前提下主动进行部分重构。被项目负责人认可并实施的。+1分/次
* 主持完成项目成员能力提升课程的。+3分/次
## 职位专属考核标准
### 助理工程师
助理工程师没有额外扣分项,但是助理工程师在试用期间绩效低于90(不含90)时将视为试用不合格。试用不合格时根据情况可选择延长试用一个月
### 工程师
* 负责的代码因没有达到[项目基本规范](./规范/README.md)的要求被项目负责人要求限期修改,并且没有按时完成的,超过限期天数=N,N*-1分/次(对不符合基本规范的代码进行修改不计入工作量,也不额外安排时间)
* 已经上线的代码,在需求和系统架构没有变更的前提下,被项目负责人要求重写超过30行的。累计每3次-1分(累计次数跨月计算)
### 高级工程师
* 负责的代码因没有达到[项目基本规范](./规范/README.md)的要求被项目负责人要求限期修改,并且没有按时完成的,超过限期天数=N,N*-2分/次(对不符合基本规范的代码进行修改不计入工作量,也不额外安排时间)
* 已经上线的代码,在需求和系统架构没有变更的前提下,被项目负责人要求重写超过30行的。-1分/次
* 负责的助理工程师没有按时完成工作的,-1分/次
## 规则修订时间
2019/9/6
## 规则生效时间
2019/9/9
\ No newline at end of file
# 项目基本规范
本规范指定了所有项目通用的基本要求,**所有人必须严格遵守本规范进行开发**。根据项目,开发者除了本规范以外,还需要遵守相应类型的项目规范。<br />
## 1、注释和说明
1. 所有注释必须和实际代码内容匹配,要严格避免复制文件对代码进行修改之后不修改注释的情况
2. 每个项目必须在根目录下有readme.md对项目整体进行说明
3. 当前目录下有超过7个子目录或文件的情况下,必须添加readme.md对各目录和文件进行整体说明,但是有额外文档或者目录下的文件是自动生成的除外
4. 每个代码文件都要有整个文件的注释,并且尽可能放在文件顶部。在readme.md里面有说明的可以除外
5. 每个函数都应该有至少一行注释和函数声明放在一起。但是函数总行数小于等于5行的可以除外
6. 禁止使用注释来代替删除,并将其应用于大块的废弃代码
## 2、编码规范
1. 必须显式声明变量,而无论使用的语言是否支持隐式变量声明
2. 单个函数不能超过100行,并应尽量避免超过50行(含空行,不含注释),当单个函数太长的时候,则将其拆分为多个功能不同的子函数
3. 代码缩进必须对齐,并且统一使用半角空格实现缩进
4. 代码缩进不允许超过7层,并应尽量避免超过5层(按对齐线的数量计算),当缩进过多时,则将其拆分为子函数或是修改代码结构。但是JSON数据结构的缩进层级不受本要求限制
5. 在同一个代码文件里面,不允许有2个或2个以上相似度超过75%的函数存在,除非函数本身行数小于等于5行
6. 单行代码不允许超过300个字符,若超过的,应当在合适的部位加入换行。但是单行内容本身就是一个超长字符串的例外
7. 单行代码不超过50个字符的单个语句必须写在同一行里面,单行代码不超过100个字符的单个语句应当尽量写在同一行里面,应当尽可能的写在同一行里面。例如:let obj = { key, item }这种代码,就不能写成4行,而应该写在1行里面
8. 不能连续使用超过5级的子对象,并尽量不大于3级。在层级过高时,使用一个中间变量来让代码更加清晰友好。例如obj.sub1.sub2.sub3.sub4.sub5.sub6,可增加中间变量let subObj = obj.sub1.sub2.sub3,然后再使用subObj.sub4.sub5.sub6
9. 循环嵌套最多3层,超过3层的必须改用其他方法实现业务逻辑
## 3、命名规范
1. 变量名的长度不允许超过20个字符,并应尽量控制在10个字符以内;函数名的长度不允许超过40个字符,并应尽量控制在20个字符以内
2. 函数和变量命名时应当尽可能使用含义准确的英文或英文缩写,实在不方便的也可以使用拼音或者拼音首字母。但是拼音和英文混用时,必须是拼音缩写在前,英文单词在后。例如协议文档,可以命名为xyDoc,但是不允许命名为xieYiDoc
3. 除了[常用变量名及缩写](./常用变量名及缩写.md)里规定的变量名以外。禁止使用单个字母作为变量名,除非该变量仅出现于声明之后的最多10行代码以内
4. [常用变量名及缩写](./常用变量名及缩写.md)里规定的变量名不得用于表达其他含义
5. 除了局部变量和内部函数以外,所有函数和变量的命名应当清晰明确而不能过于宽泛。比如item和data这类命名,可以出现在单个文件内部,或者作为一个父对象的属性名,但不能单独跨文件使用
6. 每个文件的文件名必须清晰明确,不允许使用过于宽泛的文件名,比如item和page
7. 变量和函数的命名应当精简,不允许有过多冗余信息。比如父对象是userData,然后里面的函数又命名为getUserData,这种情况就需要把函数名称精简
8. 目录和代码文件命名应当精简,不允许有过多冗余信息。比如目录本身是users,然后下面的文件名字又叫做usersXXXX,这种情况就应该把文件名精简
## 4、Git库管理规范
1. 每次提交代码必须附带注释,并且注释必须有清晰的指向性含义。比如不能使用“修正一个BUG”这样的注释,而必须写清楚“修正了XX系统的一个BUG”
2. 所有人禁止在本地直接修改master分支,master分支仅允许项目维护者在远程库操作合并
3. 所有人禁止在本地直接修改test分支,test分支必须在远程库操作合并
4. 项目维护者以外的开发者禁止在本地直接修改develop分支,项目维护者仅在进行少量修改时允许在本地直接修改develop分支并推送。develop分支可以在远程库操作合并
5. 在给项目追加新功能时,应以master为源分支新建以feature-开头的分支,如feature-xxxSystem。在完成开发后,首先应将其提交到远程库,然后合并到develop分支进行开发者测试,开发者测试通过后再将其合并到test分支进行全面测试。测试没问题之后申请合并到master分支等待发布
6. 在修复项目线上的bug时,应以master为源分支新建以fix-开头的分支,如fix-ch190903。在完成修改后,将其提交到远程库,然后在远程库合并到develop或者test分支进行测试,测试完成以后申请合并到master分支并通知项目维护者进行合并发布
7. 项目维护者必须严格按照[项目tag管理规范](./项目tag管理规范.md)来管理tag
## 5、测试规范
1. 新功能必须先放到develop分支上进行测试,经过完整功能性测试之后确定没有问题才能合并到test分支
2. 新功能在放上test分支之后,必须经过简单的功能性测试,确认功能可以运行之后才能通知对接人进行测试
3. bug修复分支直接在test分支上进行测试,测试完没有问题之后再合并到develop分支和master分支
# 扩展内容
* [常用变量名及缩写](./常用变量名及缩写.md)(2019/9/5)
* [node.js后端项目规范](./项目规范_node.js后端.md)(待编辑)
* [vue项目规范](./项目规范_vue项目.md)(待编辑)
* [小程序项目规范](./项目规范_小程序.md)(待编辑)
* [安卓原生项目规范](./项目规范_安卓原生.md)(待编辑)
* [苹果原生项目规范](./项目规范_苹果原生.md)(待编辑)
* [项目tag管理规范](./项目tag管理规范.md)(待编辑)
# 文档修订记录
* 2019/9/5:初版
\ No newline at end of file
# 常用变量名及缩写
## 约定俗成的极简变量
| 变量名 | 含义 |
|:-------|:-----|
| a | 在纯粹的数学计算函数中用作第一个参数 |
| b | 在纯粹的数学计算函数中用作第二个参数 |
| i | 通常用于for循环的索引 |
| j | 在多层循环中用于第二层for循环 |
| k | 在多层循环中用于第三层for循环,或作为key的缩写使用 |
| n | 在小型函数和局部变量中临时使用的整型数 |
| m | 在小型函数和局部变量中临时使用的整型数,通常与n同时使用 |
| s | 在小型函数和局部变量中临时使用的字符串 |
| t | 数据库事务Transaction的首字母,表示一个事务实例 |
| _ | 无 | 在多层循环中用于第三层for循环 |
## 常用变量名缩写
若有疏漏欢迎补充
| 缩写 | 原单词 | 别名 | 含义 |
|:-----|:-----|:-----|:-----|
| add | addition | 无 | 加 |
| addr | address | 无 | 地址 |
| adm | admin | 无 | 管理/管理员 |
| app | application | 无 | 应用/科目 |
| arg | argment | 无 | 参数 |
| arr | array | 无 | 数组 |
| attr | attribute | 无 | 属性/特性 |
| auth | authority / authorize | 无 | 权限 |
| avg | average | 无 | 平均值 |
| btn | button | 无 | 按钮 |
| buff | buffer | buf | 缓存 |
| calc | calculate | 无 | 计算 |
| cfg | configuration | config | 配置 |
| char | character | 无 | 字符 |
| cmd | command | 无 | 命令 |
| cmp | compare | 无 | 比较 |
| col | color/column | 无 | 列 |
| cur | current | 无 | 当前的 |
| db | database | 无 | 数据库 |
| dec | decrease / decode | 无 | 减少/解码 |
| dep | dependency / dependent / depends | 无 | 依赖 |
| dev | develop / device | 无 | 开发版/设备 |
| dict | dictionary | 无 | 字典 |
| diff | diffrent / difficult | 无 | 差异/难度 |
| dir | directory | 无 | 目录 |
| div | division | 无 | 除 |
| dst | destination | dest | 目的 |
| doc | document | 无 | 文档 |
| dup | duplicate / duplication | 无 | 副本 |
| env | environment | 无 | 环境 |
| enc | encode | 无 | 编码 |
| eq | equal | 无 | 等于 |
| err | error | 无 | 错误 |
| evt | event | 无 | 事件/活动 |
| flg | flag | 无 | 标记 |
| func | function | 无 | 函数 |
| idx | index | i | 索引 |
| inc | increment | 无 | 增加 |
| info | information | 无 | 信息/详情 |
| init | initial | 无 | 初始化 |
| img | image | 无 | 图片 |
| it | iterator | itr,iter | 迭代器 |
| len | length | 无 | 长度 |
| lib | library | 无 | 库 |
| lnk | link | 无 | 链接 |
| lst | list | 无 | 列表 |
| msg | message | 无 | 消息 |
| mid | middle | 无 | 中间的 |
| mul | multiplication | 无 | 乘法 |
| num | number | n | 整数 |
| nxt | next | 无 | 下一个 |
| obj | object | 无 | 对象 |
| op | operate | 无 | 操作 |
| opt | option | 无 | 选项 |
| pkg | package | 无 | 包 |
| pos | position | 无 | 位置 |
| pre | previous | prev | 前一个 |
| prm | parameter | param | 参数 |
| prop | property | 无 | 属性/特性 |
| pt | point | 无 | 点 |
| ptr | pointer | 无 | 指针 |
| pwd | password | 无 | 密码 |
| prod | production | 无 | 正式版 |
| ref | reference | 无 | 引用 |
| res | result / resource | 无 | 结果/资源 |
| ret | return | 无 | 返回 |
| sig | sign | 无 | 标记 |
| src | source | 无 | 源 |
| stat | status | 无 | 状态 |
| std | standard | 无 | 标准 |
| str | string | s | 字符串 |
| sys | system | 无 | 系统 |
| tbl | table | 无 | 表格 |
| tar | target | 无 | 目标 |
| tmp | temporary | temp | 临时的 |
| trans | translate | 无 | 转换 |
| txt | text | 无 | 文本 |
| usr | user | 无 | 用户 |
| util | utilities | 无 | 工具 |
| val | value | 无 | 值 |
#修订时间
2019/9/5
\ No newline at end of file
# 项目tag管理规范
\ No newline at end of file
# 项目进阶规范
本规范指定了一些判断和实施难度较高的规范要求,项目成员应当根据自己的能力尽力达成本规范所要求的内容。在阅读本规范前,应先阅读并牢记[项目基本规范](./README.md)
## 一、注释规范
规范注释是规范代码的第一步,写不好注释的人,就算技术能力再怎么高,也难以适应团队化开发
### 1、注释的基本使用
1. 多行注释:多行注释通常用于对整个代码文件进行说明,或是在重要的函数和数据结构前对其进行详细说明。多行注释有规定格式的,应当按照规定格式来编写
2. 单行注释:单行注释应用于绝大部分场合,包括对函数的进行说明,对接下来的代码进行说明,或者用于做特定的标记等
3. 代码后注释:指和代码在同一行,并在代码后的单行注释。代码后注释通常用于对变量进行说明,或者对本行内容进行补充性说明
在项目中,只允许使用以下几种注释格式之一
4. 代码中注释:指和代码在同一行,并且不在代码后的注释。除了用于占位以外,应尽量避免使用代码中注释
5. TODO标记:可以应用在任何代码注释中,并且标记在注释的最前方。TODO标记用于占位,提示开发者应当在该位置做的事情。在由于某些原因无法直接完成全部代码,或者为了赶时间暂时提交了临时使用的代码的时候。就可以用TODO标记来占位,一个典型的带有TODO标记的注释:// TODO:这里有漏洞,需要修改
### 2、应当使用注释的地方
1. [项目基本规范](./README.md)里规定了必须要使用注释的地方
2. 对全局变量和其他使用范围较大,并且变量名不能做到一目了然的变量,应当使用代码后注释
3. 函数内部分为多个代码块的时候,对无法一眼看懂的代码块应当添加对应注释
4. 代码中需要提醒开发者和维护者注意的地方,应当添加注释
5. 对比较复杂的表达式或者逻辑判断,建议添加注释
### 3、不应该使用注释的地方
1. 注释内容过多,规模过大的,应当单独建立文档进行说明,而不是作为注释放在代码文件中
2. 添加了注释之后对于阅读代码没有任何帮助的注释,不建议添加
3. 连续而琐碎的注释会影响阅读代码时的流畅性,如果连续而琐碎的注释太多,建议整理好之后放在一个语句块的前面
### 4、注意事项
1. 注释内容应当尽可能的清晰明确,避免使用函数不清的字句
2. 注释必须和代码保持同步,修改代码之后应当重新确认一下注释,并根据具体情况修改注释
## 二、代码规范
### 1、基本要求
1. 除非没有更好的替代方案,否则禁止使用全局变量
2. 对其他文件的引用,以及变量声明。尽可能的统一放在对应代码块和代码文件的头部统一管理
3. 在同一个项目内应当使用严格统一的语法来编写代码
### 2、代码分块
1. 在代码中,应该适当的使用空行来对代码进行分块
2. 在代码块中,代码的功能应当清晰明确,不能把不同的代码逻辑混在一起交替执行
3. 代码块不宜过长,通常一个代码块应当限制在10个语句之内
4. 业务复杂并且需要大量调用其他函数的来完成业务的单个函数内,应尽量将对外调用整合起来,以尽可能的避免一行一个代码块的情况出现
### 3、代码通用性
1. 数据和代码逻辑应当分离,尽可能避免在代码逻辑中使用写死的数据
2. 适当的使用中间数据,可以极大的提升模块的独立性,并减少对其他模块的依赖
3. 当进行单个模块开发的时候,尽量避免将依赖关系混入到模块逻辑中
# 文档修订记录
* 2019/9/5:初版
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment