Http 服务器变量

这里数据来自于 PHP 服务器获取到的数据, 并在这个数据基础上对 Header 进行说明并进行实地验证, 更多的 Header 的信息查看 HTTP Headers

环境变量

服务器信息以及服务器接收到的响应数据

  • USER : ‘duoli’

当前程序的运行用户

  • HOME : ‘/Users/duoli’

当前程序的用户主目录

  • REDIRECT_STATUS : 200

PHP CGI 模式下的重定向状态, 使用 --enable-cgi-redirect 开启, 默认不能进行重定向

  • SERVER_PORT : 80

服务器端口号

  • SERVER_ADDR : 127.0.0.1

服务器地址, 默认是当前服务器的内网IP

  • REMOTE_PORT : 59888

当前连接到 Web 服务器所使用的端口号

  • REMOTE_ADDR : 127.0.0.1

当前用户的服务器地址, 如果服务器之间的数据传输启用了代理, 这里的地址会是最后一个代理的地址(如果需要对此地址进行覆盖改写, 需要从服务器中配置此变量)

  • SERVER_SIGNATURE : ‘’

包含了服务器版本和虚拟主机名的字符串

  • SERVER_SOFTWARE : nginx/1.21.5

当前服务器的版本号

  • GATEWAY_INTERFACE : CGI/1.1

当前网关接口

  • REQUEST_SCHEME : http

当前地址的请求协议

  • SERVER_PROTOCOL: HTTP/1.1

当前请求的传输协议

  • SERVER_NAME : ‘127.0.0.1’

当前运行脚本所在的服务器的主机名。如果脚本运行于虚拟主机中,该名称是由那个虚拟主机所设置的值决定

  • DOCUMENT_ROOT : ‘…./start/public’

当前请求文件的真实目录

  • DOCUMENT_URI : ‘index.php’

  • SCRIPT_NAME : ‘index.php’ 当前请求的文件名称

  • REQUEST_URI : ‘/misc/http/server’

当前请求的URI路径

  • CONTENT_LENGTH : ‘’

发送给接收方的消息主题的大小

  • CONTENT_TYPE : ‘’

用于指示资源的MIME类型

  • REQUEST_METHOD : ‘GET’

当前的请求方法

  • QUERY_STRING : ‘’

当前的查询字符串数据

  • SCRIPT_FILENAME : ‘…/public/index.php’

当前脚本的文件路径

  • FCGI_ROLE : ‘’

当前 FastCGI 的角色, 可以使用的角色为 [RESPONDER|AUTHORIZER|FILTER] FastCGI

  • PHP_SELF : ‘index.php’

当前执行脚本的文件名,与 document root 有关。例如,在地址为 http://example.com/test.php/foo.bar 的脚本中使用 $_SERVER['PHP_SELF'] 将得到 /test.php/foo.bar。__FILE__ 常量包含当前(例如包含)
文件的完整路径和文件名。

  • REQUEST_TIME_FLOAT: ‘1648284041.8815’
  • REQUEST_TIME : ‘1648284041’

当前请求时间

  • HTTPS

如果脚本是通过 HTTPS 协议被访问,则被设为一个非空的值。Note: 注意当使用 IIS 上的 ISAPI 方式时,如果不是通过 HTTPS 协议被访问,这个值将为 off。

  • REMOTE_HOST

浏览当前页面的用户的主机名。DNS 反向解析不依赖于用户的 REMOTE_ADDR。 Note: 你的服务器必须被配置以便产生这个变量。例如在 Apache 中,你需要在 httpd.conf 中设置 HostnameLookups On 来产生它。参见 gethostbyaddr()。

  • PATH_TRANSLATED

当前脚本所在文件系统(非文档根目录)的基本路径。这是在服务器进行虚拟到真实路径的映像后的结果。 Note: 自 PHP 4.3.2 起,PATH_TRANSLATED 在 Apache 2 SAPI 模式下不再和 Apache 1 一样隐含赋值,而是若 Apache 不生成此值,PHP 便自己生成并将其值放入
SCRIPT_FILENAME 服务器常量中。这个修改遵守了 CGI 规范,PATH_TRANSLATED 仅在 PATH_INFO 被定义的条件下才存在。 Apache 2 用户可以在 httpd.conf 中设置 AcceptPathInfo = On 来定义 PATH_INFO。

  • SCRIPT_FILENAME

当前执行脚本的绝对路径。 Note: 如果在命令行界面(Command Line Interface, CLI)使用相对路径执行脚本,例如 file.php 或 ../file.php,那么 $_SERVER['SCRIPT_FILENAME'] 将包含用户指定的相对路径。

  • PHP_AUTH_DIGEST

当作为 Apache 模块运行时,进行 HTTP Digest 认证的过程中,此变量被设置成客户端发送的“Authorization” HTTP 头内容(以便作进一步的认证操作)。

  • PHP_AUTH_USER

当 PHP 运行在 Apache 或 IIS(PHP 5 是 ISAPI)模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的用户名。

  • PHP_AUTH_PW

当 PHP 运行在 Apache 或 IIS(PHP 5 是 ISAPI)模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的密码。

  • AUTH_TYPE

当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是认证的类型。

  • PATH_INFO

包含由客户端提供的、跟在真实脚本名称之后并且在查询语句(query string)之前的路径信息,如果存在的话。例如,如果当前脚本是通过 URL http://www.example.com/php/path_info.php/some/stuff?foo=bar
被访问,那么 $_SERVER['PATH_INFO'] 将包含 /some/stuff。

阅读更多

Git 常见问题

Git 设置代理来访问服务器

全局代理

1
2
3
4
5
6
7
# 设置代理
$ git config --global http.proxy http://127.0.0.1:1087
$ git config --global https.proxy https://127.0.0.1:1087

# 取消代理
$ git config --global --unset http.proxy
$ git config --global --unset https.proxy

设置项目代理

1
2
3
4
5
6
7
# 设置代理
$ git config --local http.proxy 127.0.0.1:1086
$ git config --local https.proxy 127.0.0.1:1086

# 取消代理
$ git config --local --unset http.proxy
$ git config --local --unset https.proxy

给指定的 URL 设置代理

1
2
3
4
5
6
[http "https://github.com/"]
proxy = http://127.0.0.1:1086
[https "https://github.com/"]
proxy = http://127.0.0.1:1086
[http "https://my.comapnyserver.com/"]
proxy = ""

Git 保留最新提交记录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Checkout
git checkout --orphan latest_branch

# Add all the files
git add -A

# Commit the changes
git commit -am "commit message"

# Delete the branch

git branch -D master

# Rename the current branch to master

git branch -m master

# Finally, force update your repository

git push -f origin master

Git 保存请求的账号密码

https 方式每次都要输入密码,按照如下设置即可输入一次就可以很长时间不用再手输入密码。

第一步:设置邮箱和密码

1
2
$ git config --global user.email "your email"
$ git config --global user.name  "your username"

根据自己的需求执行下面的任意一条命令

第二步:

1
2
3
4
5
6
7
8
9
10
11
# 设置记住密码(默认15分钟):
$ git config --global credential.helper cache

# 如果想自己设置时间,可以这样做, 这样就设置一个小时之后失效
$ git config credential.helper 'cache --timeout=3600'

# 长期存储密码:
$ git config --global credential.helper store

# 增加远程地址的时候带上密码也是可以的。(推荐)
$ http://yourname:password@git.oschina.net/name/project.git

运行相关命令, 输入账号密码, 如果正确则下次不必重新输入, 在 git 目录中存在两个文件 .gitconfig, .git-credentials, 里边放置的是凭证的信息

Git 推送 github 代码出现 443: Operation timed out 问题

推送到 https://github.com/{username}/{project}.git
fatal: 无法访问 ‘https://github.com/...':Failed to connect to github.com port 443: Operation timed out
Completed with errors, see above

如果出现 raw.githubusercontent.com 之类的问题都可以采用此类方法解决

解决: hosts 中加入 ip 映射

查询真实 IP

通过 IPAddress.com, 输入 github.com 查询到真实 IP 地址, 然后修改 hosts 映射, 这里需要在本地 ping 下指定的查询出来的 ip , 否则也无法访问

删除本地所有的 Tag 并获取服务端所有

1
2
# 删除本地所有tag 并获取服务端所有
$ git tag -l | xargs git tag -d && git fetch --tags

git pull 冲突终极解决方案

服务端 git pull 或 git checkout 报以下错误

Your local changes to the following files would be overwritten by merge
error: Your local changes to the following files would be overwritten by merge:

解决方案:

1
2
$ git reset --hard HEAD
$ git clean -f -d

参考

VSCode 插件

存储图片到 Aliyun(推荐)

安装插件 Paste To Aliyun Oss

安装之后可以使用 ctrl + cmd + v 来将图片直接粘贴到阿里云并把地址复制到 vscode 中

本地图片粘贴 [Paste Image]

安装插件 Paste Image

安装之后可以使用 alt + cmd + v 来将图片直接粘贴到编辑器中,
直接粘贴的图片默认位置和命名并不符合我们的要求, 所以需要重新进行配置

配置日期的参考文档: Moment 格式

1
2
3
4
5
6
7
8
9
{
"settings": {
"pasteImage.basePath": "${projectRoot}",
"pasteImage.defaultName": "Y/MMDD/HHmmss",
"pasteImage.prefix": ".. image:: /",
"pasteImage.path": "${projectRoot}/_static/images/",
"pasteImage.encodePath": "none"
}
}

这样我们粘贴图片的之后就可以直接将文件粘贴到
/_static/images/2020/0131/191053.png 类似目录下

设置为中文语言


1). 查找是否安装中文插件

2). 设置选择中文语言

打开 View -> Command Palette 搜索 Configure Display Language, 选择 zh-cn

  1. 重启, 这样显示便是中文了

PHP 开发 - 岗位职责

岗位职责

把需求或产品实现为用户可用的软件产品

  • 参与项目框架设计、系统分析及流程控制、沟通对接等工作。
  • 独立或者分组进行针对项目需求的功能开发和优化。
  • 拥有良好的代码习惯,要求结构清晰,命名规范,逻辑性强,代码冗余率低;
  • 根据项目开发进度和任务分配,开发相应的应用模块。
  • 根据需要不断修改完善项目功能。
  • 参入核心代码的编写
  • 运营数据处理和分析

任职资格

  • 2 年及以上 PHP 开发经验
  • 具有 MySQL 索引优化、查询优化和存储优化经验、PHP 缓存技术、静态化设计方面的经验,要求随时随地贯彻最优化开发的思想,所负责的项目须能承担繁重的访问压力, 熟悉大数据量下性能管理及优化,并有较强数据库规划能力
  • 精通 PHP/MySQL 开发,精通 memcache、squid、redis 等缓存技术者优先;
  • 悉 MVC 开发,掌握部分开源 PHP 框架, Laravel 5 等;
  • 熟悉 Javascript 语言和 HTML 语言熟悉 HTTP 协议及 W3C 相关互联网规范,熟练掌握 XHTML、CSS、 DIV 等页面技术;
  • 熟悉 Unix/Linux 操作系统和开发环境
  • 具有优良的编程风格和习惯, 要求结构清晰、命名规范、逻辑性强、代码冗余率低
  • 有创新思想,敢于挑战新事物,了解用户体验
  • 责任心强,良好的对外沟通和团队协作能力,能承受工作压力, 具有项目管理经验优先
  • 团队协同工具少不了的(Git+)

加分项目:

  1. 有大型负载开发
  2. 能够编写项目技术文档者优先考虑
  3. 有成熟作品和独立开发整站的经验

氛围足够轻松和舒适

  1. 良好的技术提升空间
  2. 全栈/高阶工程师的发展方向
  3. 济南范围内高薪待遇和高薪目标, 有项目管理经验继续加薪
  4. 缴纳五险一金, 法定节假日
  5. 良好的办公环境和高配的 Mac 办公机器

岗位评级

初级

  1. 能够独立配置 Linux 上的 Web 运行环境,包括 PHP/MySQL/Nginx/Apache 等软件及其相关扩展
  2. 知道如何使用 PHP 手册、如何使用百度、谷歌等搜索引擎快速解决问题;
  3. 了解面向对象软件开发基本概念;
  4. 了解 mvc 思想和运行机制
  5. 熟练利用 MySQL 进行动态应用开发;
  6. 能够独立开发留言板、小型 CMS 等应用;
  7. 能够独立编译安装 PHP Extension;
  8. 对常用的 Linux 命令能够熟练使用;
  9. 能够使用 ZF/Yii/CI 等框架进行应用开发

中级

  1. 对面向对象开发有深入了解
  2. 能熟练应用常用设计模式来应用开发
  3. 了解 php 框架底层实现原理和设计思想
  4. 能够对 mysql 等数据库进行性能优化
  5. 了解并能应用常用缓存技术 redis/memcache 等
  6. 熟练掌握常用的数据结构和算法
  7. 熟练使用 composer 并能够自己开发 composer 扩展包

1、能够独立解决 Windows/Linux 上的 web 运行环境中出现的问题,能够熟练对 Web 运行环境进行优化;

2、了解如何使用 C 语言进行 PHP Extension 的开发;

3、熟练使用 Memcache/Redis 等工具对 Web 应用进行优化;

5、可以熟练进行较为复杂的 shell 编程;

6、能够对 MySQL 等数据库进行性能优化,能够独立查找并解决 Web 应用中的性能问题;

7、深入理解面向对象软件开发原则,对设计模式有深入学习、研究;

8、熟练掌握常见的数据结构及算法;

9、对 ZF/YII/CI 等框架源代码有过研究,了解框架精髓;

高级

  1. 了解 php 工作机制及 php-fpm 运行机制
  2. 熟悉 php 内存性能和效率优化
  3. 对 zend 引擎有基本了解
  4. 对 swoole, workerman 异步多线程有深入了解
  5. 对 redis/memcache 有深入了解
  6. 对分布式, 高并发系统有深入了解
  7. 有自主开发框架的能力

1、熟练利用 C 语言进行 PHP Extension 的开发,并能够快速解决 Web 运行环境出现的复杂问题;

2、对 Linux 系统有深入的研究,可以解决 Linux 系统出现的复杂问题;

3、对 MySQL 索引优化、Memcached 实现等工具的实现原理有深刻理解;

4、对分布式、高并发系统有深入研究;

5、在 PHP 领域中主导或参与部分开源项目,对 PHP 行业发展做出较为明显的贡献;

基本技能

  1. 基本能力
  • 搭建开发环境, 并且能够处理因为开发环境问题导致的问题

    • nginx

      • 413 无法上传图片
      • 无响应, 但是服务器能够正常访问(代理问题)
      • 服务器提交但是返回 500 , 查询 nginx 日志看 127.0.0.1:9000 端口的 cgi 响应
      • 根据日志来找错误

-php - 无法加载指定扩展 (进行扩展的安装) - 500 错误 / 一般是权限问题 - 通过 PHP 错误日志来处理问题所在

  • mysql

    • 表的创建/修改
    • 表的 [增 / 删 / 改 / 查]
    • 建立基本索引
  • 其他服务

    • supervisor
    • centrifuge
    • crontab
  • 代码管理

    • git 版本管理工具

      • git 提交/推送
      • git 代码合并
      • 提交合并请求
      • 代码审核(Review)
  1. 基础能力

    • php 基础

      • 类, 对象
      • 函数基础
    • Mysql 基础

      • 索引
      • mysql 基础函数
      • mysql 慢查询优化
    • Linux 服务器

      • 基本环境搭建
      • 服务配置维护
    • 前端技术

      • html, css, JavaScript
      • vue, react 框架

通用注释规范

在开发过程中会用到各种各样的配置文件, 但配置文件的规范可能有较大的不同, 这里对规范进行统一的说明

以下文档使用 全屏模式观看, 否则可能会出现样式错乱

Nginx / Env

支持 # 类型的注释, Env 使用注释和 Nginx 注释相同, 采用 # 进行单行注释, 注释风格如下

1
2
3
4
5
6
# -----------------------------------------------------
# Long Comment
# -----------------------------------------------------

# short Comment
# -----------------------------------------

Centrifugo(.ini)

Centrifugo 均使用 ini 后缀, 配置 = 前后不允许存在空格

Php / Javascript / Css

支持 /*...*/ 类型的注释均使用此格式

1
2
3
4
5
6
7
8
9
10
11
// 长注释
/*
|------------------------------------------------------------------
|
|------------------------------------------------------------------
|
*/

// 短注释
/*
* ---------------------------------------- */

[转+] 解决 Webstorm 不支持 nodejs 等语法提示和补全

在使用 Webstorm 写 es6、node 的时候,会出现没有语法提示甚至是产生波浪线,例如常用的 require, import

不仅是内置函数语法,不仅是 js,在一些第三方 npm 库(比如 element-ui),在 vue/html 等上也被黄色背景色标上“未知标签名”的语法提示

既影响美观,又不支持代码候选补全,实在对不起 WebStorm 前端开发利器的称号。

解决方法

  1. 设置 Webstorm js 语法支持到 es6(或根据需要选择)

打开 :  Preferences | Languages & Frameworks | JavaScript

将 JavaScript Language version 更改为 项目所需要的版本,

  1. 下载 node 语法库

方法 1: 推荐

1
$ yarn add @types/node -D

方法 2: 依赖于编辑器

打开 : Preferences | Languages & Frameworks | JavaScript | Libraries

选择下载, 选中 node

下载完成后 启用 @types/node

  1. 不要过滤 node_modules 文件夹!

打开 Preferences | Editor | File Types; 取消 node_modules 此项

因为语法库就是在来自本机和当前项目的 node_modules文件夹中。

其实过滤 node_modules 文件夹是有一定道理的,它虽然总体积不大,每个文件体积也小,但是它文件数量巨大,特别是较大的项目,node_modules 包含的文件数量多似繁星…,如果让  Webstorm 加载进来,轻则出现一小段时间软件卡顿,重则电脑长时间崩溃,当然这和电脑的性能有关。所以有一些博客可能会建议开发者特别是初学者在设置中过滤掉 node_modules 文件夹。

虽然加载 node_modules 会让电脑卡顿一段时间,但是给 Webstorm 足够时间,在电脑性能不会太差的情况下还是可以加载完的,换来的编程便利还是值得的。

然后就慢慢等待加载完毕

加载完毕之后,如果当前项目下也有 node_modules,也会自动挂到 JavaScript Library 中

效果
设置后,不仅没有语法波浪线,在输入的时候已经有代码候选补全,并且按 ctrl 点击还能跳转查看源码

标签组件名也能补全

标签也不会出现语法背景黄色,并且还支持自定义属性参数的补全

参考文章

测试

一、测试流程

A) 测试前准备

  • 准备测试所需要的环境,环境分为:本地、预发、线上。
  • 填写文字版测试单,确定要进行测试的版本和所属的项目,计划测试的时间(开始/结束时间),确定服务端的版本和分支以及客户端的版本和操作系统。
  • 建立测试单,测试单命名标准:所属产品+操作系统+版本号+测试次数(包含第几轮回归),建立好测试单后关联相关用例。

B) 确认资料

  • 确认后台配置。
  • 检查项目相关内容是否正确

C) 首轮测试

对被测软件进行一次全面的测试,测试用例 100%执行。

D) 回归测试

对首轮测试提的 BUG 进行回归测试,测试 BUG 内容及其相关联内容,每进行一轮回归测试需由测试组织一次总结会,参与人员包括:测试、相关开发人员,主要内容:大体是对测试中出现的问题进行总结,目的是为了让大家认识到这个问题,在下次的项目中避免再发生同样的问题,提高工作效率,时间在 15 分钟之内。

E) 回归测试完成时间,并进行确认

1 测试:

每进行一轮测试需等开发修复完 Bug 后再进行下一轮测试,不能尚未修复完 Bug 就进行测试,一定要及时跟踪 Bug 状态。

2 开发:

Bug 修复完成的时间:

测试根据测试的内容确定 Bug 后,需给开发留出 1-1.5 天的时间修复 Bug 并进行确认,根据 Bug 的修复难易程度,修复时间会提前或者延后,延后时间为 3 小时,时间不宜过长。

责任人:

看出现错误的原因,是前端问题还是后端问题还是 UI 问题,相应指派给不同的负责人,由该负责人修复 Bug,修复完 Bug 后一定要及时改变禅道上 Bug 的状态,以便测试进行下一步工作。

F) 复测

当被测软件符合上线标准,应对其进行一次全面的复测,已保证功能可以正常实现。

G) 测试总结会

每次测试完一个项目后,该项目已达到上线标准,需在上线前开一个测试总结会,由测试组织开展;
参会人员:产品, UI, 测试、相关开发人员;
内容:大体包括开始、完成、总结这几个部分,测试应当在总结中发现尚未覆盖的用例并进行完善,需总结测试中出现的问题,目的是为了让大家认识到这个问题,在下次的项目中避免再发生同样的问题,提高工作效率,时间在 15 分钟之内。

二、上线标准

A) BUG 占总测试用例的比例

A 类错误 B 类错误 C 类错误 D 类错误
<4%

对于每一次测试,当没有发现致命性错误和严重性错误和一般性错误,轻微性错误数量小于测试用例总数的 4%,功能实现,且可以正确执行,则认为系统通过本次测试。

B) 缺陷修复率标准

1)  A、B、C 级错误修复率必须达到 100%。
2)  D 级错误修复率应达到 96%以上。
注:项目紧急时,C 级错误修复率应达到 96%以上,D 级错误修复率应达到 90%以上。

C) 覆盖率标准

测试用例执行覆盖率应达到 100%。
注:如软件发现 Bug,但没有该项测试用例,应及时进行补充。

三、上线重点测试

测试把软件当中的重点内容列举出来:

  1. 主要功能;
  2. 用户用的比较频繁的功能;
  3. 一旦出现缺陷可能对用户造成重大影响的功能;

列举出功能点后,执行一遍测试用例。
上线后也可以让非开发测试人员进行测试,收集问题,增加系统的稳定性。

快速修复

看出现错误的原因是属于前端还是后端还是 UI 问题,找到相应的负责人进行修复。

附录

A) 里程碑测试

对开发自己制定的阶段性计划进行测试,主要是看开发有没有完成自己制定的阶段性计划,保证开发进度正常进行,帮助开发确定这个阶段完成的标准以及下个新阶段启动的条件或前提,时刻跟进开发的进度。

B) 自动化测试

了解安装自动化测试所需软件,熟悉软件的使用,制定相应的测试计划。

C) 测试流程

  1. 产品文档(产品经理)
  2. 设计文档(开发者)
    • 数据库设计
    • 接口设计
    • 流程及类的设计
  3. 整理测试用例
  4. 测试
  5. 自动化部署/上线

D) 白盒测试

测试需从接口角度发现问题,并快速定位问题,确定问题是前端还是后端问题,直接指派给相关负责人。

数据架构师 - 岗位职责

数据架构师岗位职责:

1、主导数据中台系统数据架构设计,编写相关技术文档;

2、主导公司数据分析工具集的落地,搜索产品、图分析、时空分析、自定义建模分析工具,交互分析工具,统计报表分析等产品设计;

3、基于项目需求,编写技术方案,为公司大数据项目落地提供技术指导;

4、把握大数据最新技术应用及发展方向,开展相应技术预研;

5、跟踪大数据行业进展及市场动态,不断创新完善设计方法论和解决方案,能够突破创新。

任职要求:

1.精通离线和实时数据处理和图计算框架等;

2.熟悉大数据技术生态圈,精通大数据技术架构,有大数据平台构建经验;

3.有实际大规模数据(10TB 级以上)处理经验优先;

4.有数据治理或人工智能相关项目经验;

5.本科及以上学历,4 年以上工作经验; .

6.具有项且管理经验优先

产品 & 设计

产品

需求

产品应有描述需求, 并浓缩需求为可理解的语言

流程

应有流程图来表示出现问题的各种分支以及重点约定

流程中操作应描述

  • 前置条件
  • 操作影响 / 结果

设计

颜色的管理

颜色命名以及使用参考 Vant 主题定制

颜色

应描述颜色的标识以及变种

模块颜色定义

应描述模块的模块使用颜色的各种定义, 以及使用的颜色的标识

渐进式布局

机型

  • 字体大小不同在不同机型上的展示风格
  • 效果图在不同机型上的展示样式

图标的管理

ICON

图标的管理以及命名都是 UI 来进行管理

[译+] 使用 PhpStorm 开发 Laravel 应用

很多 PHP 程序员使用 laravel 创建他们的应用程序。laravel 是一个免费开源的 PHP web 应用程序框架。它基于多个 Symfony 组件,提供了一个开发框架,包括 authentication, routing, sessions, caching 等模块.
去年夏天, 我们介绍了 支持 Blade 。blade 是 Laravel 的模板语言, 对艺术家友好,这个 Laravel 程序员的命令行工具, 可以在 PhpStorm 中工作. 使用 Laravel 插件 和 Laravel IDE 帮助器, 我们可以进一步扩展 PhpStorm 对 Laravel 应用的支持。下面让我们看怎么做!

安装 Laravel IDE 助手

  • 官方方式

    首先确认 Composer 在我们的项目中是可用的, 我们可以使用 Composer | Add dependency… 右键菜单安装 Laravel 5 IDE Helper Generator 到我们的项目. 搜索 barryvdh/laravel-ide-helper,并且点击 Install 下载并添加到项目.

  • [译注]自助方式

    因为我们是在项目中使用, 所以我们在项目中添加这个功能, 在 composer.json 中添加 require-dev 分支
    laravel 4.* , 这里的版本应该填写 1.*

1
2
3
4
5
"require-dev": {
// ...
"barryvdh/laravel-ide-helper": "2.*"
// ...
},

然后使用命令 composer update -vvv 来更新程序包

注册 'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider' 服务到我们的应用, 即写入到 config/app.php 中的 provider 中 , 这样在 artisan list 中便存在了ide-helper的命令, 运行 artisan ide-helper:generate, PhpStorm 就会有代码完成功能,并且有 Laravel 的语法高亮.

PhpStorm 中的 Laravel 插件

为了进一步提升我们的 Laravel 体验,我们也可以安装 Laravel 插件. 在 Settings (Preferences) | Plugins, 点击 Browse repositories… 按钮并搜索 Laravel. Install plugin 按钮会下载并安装插件到 IDE.

重启 IDE 并启用插件( Settings (Preferences) | Other Settings | Laravel Plugin | Enable Plugin for this Project). PhpStorm 知道 Laravel 的界面做什么, 并且提供(controllers,views, routes, configuration, translations、等)的代码完成功能!

当然不只是代码自动完成,使用 Ctrl+Click (CMD+Click Mac OS X) 或者 Go To Declaration(转到定义) (Ctrl+B / CMD+B), PhpStorm 将会导航到那里, 比如配置项的声明。
关于使用 Blade 模板,Laravel 插件也可以提高体验, 比如:@section 指令的自动完成.
想了解更多吗? 查看我们的 Laravel 教程,这里包含了 PhpStorm 为 Laravel 开发准备的全部东西, 包括代码自动完成,导航,自动代码检查,命令行工具支持,调试和单元测试!

还可以在composer.jsonpost-update-cmd中加入命令保证 helper在每次 update 的时候都会更新,如下:

1
2
3
4
5
"post-update-cmd": [
"php artisan clear-compiled",
"php artisan ide-helper:generate",
"php artisan optimize"
],

另外,如果你的 model 是 extend 的 Eloquent,这个插件还可以给项目中的 model 添加 phpDoc,直接显示字段名,便于阅读,用法

1
php artisan ide-helper:models User

需要修改composer.json,在 require-dev段添加

1
2
3
"require-dev": {
"doctrine/dbal": "~2.3"
},

参考文章:

JavaScript - 编码规范 v1.0

1. 命名规则

使用含义丰富的名字

杜绝使用无意义的单字母命名

1
if (currentYear > 2009) ...

组成

命名应该由 26 个大小写字母(A .. Z, a .. z),10 个数字(0 .. 9), $(美元符号)_(下划线) 组成。不要使用国际字符(例如中文, emoji 表情),因为它们可能不易读或者不能在任何地方都能容易理解。不要使用 \(反斜线符号), $ 符号仅仅作为被选择的 dom 进行使用

下划线

不要使用 _(下划线) 作为变量名称的首字母。它被用来表示私有,但是它实际上不提供私有性。
文件或类中的 私有 属性, 变量和方法名应该以下划线 _ 开头.

首字母小写

大多数变量和方法名应该以小写字母开始。[变量/函数]杜绝使用拼音命名

类首字母使用大写

必须使用 new 前缀的构造函数应该以大写字母开始。JavaScript 不会在省略 new 时报编译期警告或运行时警告。
不使用 new 时会发生坏事情,所以大写首字母规范是我们拥有的唯一的防御。

常量使用大写

常量的形式如: NAMES_LIKE_THIS, 即使用大写字符, 并用下划线分隔. 你也可用 @const 标记来指明它是一个常量. 但请永远不要使用 const 关键词,关键词 const, 因为 IE 不能识别, 所以不要使用

变量声明

声明变量必须加上 var 关键字 . JavaScript 不强求这点,但是这样做会让程序更易读,并且会让探测未声明的可能变成隐式的 globals 的 变量更容易。
var 语句应该为方法体内的第一个语句。
每个变量声明应该自己占一行并有注释。它们应该按字母顺序排列。

1
2
3
var currentEntry; // currentyly selected table entry
var level; // indentation level
var size; // size of table

JavaScript 没有块作用域,所以在块里定义变量可能会让有其它 C 家族语言经验的程序员迷惑。在方法顶端定义所有变量。 尽量少使用全局变量。隐式的全局变量应该从来不使用。

方法声明

所有的方法应该在它们使用前声明。内部方法应该位于 var 语句后面。这让哪些变量包含在它的 scope 里更清楚。
方法体本身缩进 Tab。} (右大括号)应该和方法声明处对齐。

1
2
3
4
5
6
7
function outer(c, d) {
var e = c * d;
function inner(a, b) {
return (e * a) + b;
}
return inner(0, 1);
}

这个规范可以和 JavaScript 很好的工作,因为在 JavaScript 里方法和对象字面量可以放在允许表达式的任何位置。它使用内部方法和复杂结构提供最好的可读性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function getElementsByClassName(class_name) {
var results = [];
walkTheDOM(document.body, function (node) {
var a; // array of class names
var c = node.className; // the node's classname
var i; // loop counter
// If the node has a class name, then split it into a list of simple names.
// If any of them match the requested name, then append the node to the set of results.
if (c) {
a = c.split(" ");
for (i = 0; i < a.length; i += 1) {
if (a[i] === class_name) {
results.push(node);
break;
}
}
}
});
return results;
}

如果一个方法字面量为匿名的,则在“function”和“(”(左圆括号)之间应该有一个空格。如果省略空格,则它可能看起来方法名是 function”,而这是错误的。

1
2
3
4
5
6
7
8
9
div.onclick = function (e) {
return false;
};
that = {
method: function () {
return this.datum;
},
datum: 0;
};

尽量少用全局方法。

方法参数/入参

方法中的参数使用 蛇形写法, 这里的方法包含回调函数, 定义函数, 类方法

1
2
3
4
function getElementsByClassName(class_name) {
var results = [];
// ...
}

2. 文件及格式化

JavaScript 文件

JavaScript 程序应该作为一个.js 文件存储和发布。
JavaScript 代码不应该嵌入在 HTML 文件里,除非那些代码是一个单独的会话特有的。HTML 里的 JavaScript 代码大大增加了页面的大小,并且 很难通过缓存和压缩来缓解
<script src="filename.js"> 标签应该在 body 里越靠后的位置越好。这减少了由于加载 script 而导致的其它页面组件的延迟。没有必要使 language 或者 type 属性。由服务器而不是 script 标签来决定 MIME 类型。
文件名应该使用小写字符, 以避免在有些系统平台上不识别大小写的命名方式. 文件名以.js 结尾, 不要包含除 - 和 _ 外的标点符号(使用 - 优于 _).

继续缩进

当一条语句不能在单独一行写完时,可能有必要拆分它。在操作符后进行拆分,最好是在逗号后面拆分。
操作符后面进行拆分减少了通过插入分号伪装 copy-paste 错误的可能性。下一行应该缩进 + 4空格

注释

慷慨的写注释。留下一些供需要理解你做了什么的人们(可能是你自己)下次阅读的信息是有用的。注释应该书写良好和清晰,就像它们 标注的代码一样。偶尔小幽默一把也是可以的。挫折和怨恨就别写了。
更新注释非常重要。错误的注释让程序更难读懂和理解。
让注释有意义。更多的关注于不能马上可见的东西。不要用如下内容浪费读者的时间:

1
i = 0; // Set i to zero.

一般使用行注释。把块注释用于正式文档或外部注释。
修改的重要的注释使用 /* Comment (User)[2014-05-06] */ 来进行注释, 其余采用简洁注释

空格缩进

使用 空格 进行缩进, 使用正确的缩进来表明嵌套层次, 4 个空格作为一个缩进

文件编码为 utf-8

空行

空行通过将逻辑相关的代码放到一起来增加可读性。

空格

空格应该用于如下情况:

  • 关键字后面跟“(”(左圆括号)时应该用一个空格隔开。
  • 方法名和方法的“(”(左圆括号)之间不要有空格。这利于区分关键字和方法调用。
  • 所有的二元操作符,除了“.”(圆点)、“(”(左圆括号)和“[”(左中括号),都应该使用一个空格来和操作数隔开。
  • 一元操作符和操作数之间不应该使用空格隔开,除了操作符是一个单词时,如 typeof。
  • for 语句控制部分的每个“;”(分号)应该在后面跟一个空格。
  • 每个“,”(逗号)后面应该跟一个空格。

分号

总是使用分号.
如果仅依靠语句间的隐式分隔, 有时会很麻烦. 你自己更能清楚哪里是语句的起止.
而且有些情况下, 漏掉分号会很危险

数组和对象的初始化

如果初始值不是很长, 就保持写在单行上:

1
2
var arr = [1, 2, 3];  // No space after [ or before ].
var obj = {a: 1, b: 2, c: 3}; // No space after { or before }.

初始值占用多行时, 缩进 2 个空格.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Object initializer.
var inset = {
top: 10,
right: 20,
bottom: 15,
left: 12
};
// Array initializer.
this.rows_ = [
'"Slartibartfast" <fjordmaster@magrathea.com>',
'"Zaphod Beeblebrox" <theprez@universe.gov>',
'"Ford Prefect" <ford@theguide.com>',
'"Arthur Dent" <has.no.tea@gmail.com>',
'"Marvin the Paranoid Android" <marv@googlemail.com>',
'the.mice@magrathea.com'
];

比较长的标识符或者数值, 不要为了让代码好看些而手工对齐. 如:

1
2
3
4
5
WRONG_Object.prototype = {
a : 0,
b : 1,
lengthyName: 2
};

函数参数

尽量让函数参数在同一行上. 如果一行超过 80 字符, 每个参数独占一行, 并以 Tab 缩进, 或者与括号对齐, 以提高可读性. 尽可能不要让每行超过 80 个字符. 比如下面这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
// renaming without reindenting, low on space.
goog.foo.bar.doThingThatIsVeryDifficultToExplain = function(
veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo,
tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) {
// ...
};
// survives renaming, and emphasizes each argument.
goog.foo.bar.doThingThatIsVeryDifficultToExplain = function(
veryDescriptiveArgumentNumberOne,
veryDescriptiveArgumentTwo,
tableModelEventHandlerProxy,
artichokeDescriptorAdapterIterator) {
};

二元和三元操作符

操作符始终跟随着前行, 这样就不用顾虑分号的隐式插入问题. 如果一行实在放不下, 还是按照上述的缩进风格来换行.

1
2
3
4
5
6
7
8
var x = a ? b : c;  // All on one line if it will fit.
// Indentation +4 is OK.
var y = a ?
longButSimpleOperandB : longButSimpleOperandC;
// Indenting to the line position of the first operand is also OK.
var z = a ?
moreComplicatedB :
moreComplicatedC;

需要时候使用括号

不要滥用括号, 只在必要的时候使用它.
对于一元操作符(如 delete, typeof 和 void ), 或是在某些关键词(如 return, throw, case, new )之后, 不要使用括号.

字符串

使用 ' 优于 "
单引号 ' 优于双引号 ". 当你创建一个包含 HTML 代码的字符串时就知道它的好处了.

3. 语句

简单语句

每行应该包含至少一个语句。在每个简单语句末尾添加一个“;”(分号)。注意一个给方法字面量或对象字面量赋值的赋值语句仍然是一个赋值语句,所以也必须以分号结尾。
JavaScript 允许任何表达式作为语句使用。这可能产生一些错误,特别是在插入分号时。唯一可以当作语句使用的表达式是赋值表达式和调用表达式。

复合语句

复合语句是包含一个用“{}”(大括号)包围语句列表的的语句。

  • 包围的语句应该缩进 Tab。
  • “{”(左大括号)应该位于开始复合语句的行的末尾。
  • “}”(右大括号)应该新起一行并且和相匹配的“{”所在那行的起始位置对齐
  • 当语句是控制结构的一部分时,所有语句都应该用括号包围,即使是单行语句,例如 if 或 for 语句。这让添加语句更容易而且不会引起 Bug。

4. 标签

语句标签是可选的。只有如下语句需要被标签标识: while,do,for,switch。

return 语句

具有值的 return 语句不应该使用“()”(圆括号)包围值。返回值表达式必须和 return 关键字在同一行从而避免插入分号。

if 语句

if 语句应该使用如下格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# single
if (condition) {
statements;
}
#
if (condition) {
statements;
} else {
statements;
}
#
if (condition) {
statements;
} else if (condition) {
statements;
} else {
statements;
}

for 语句

for 语句应该使用如下格式:

1
2
3
4
5
6
7
8
# 和数组使用
for (initialization; condition; update) {
statements;
}
# 和对象使用
for (variable in object) {
statements;
}

第一种格式应该和数组使用。
第二种格式应该和对象使用。注意添加到对象的 prototype 中的成员将被包含在遍历中。通过使用 hasOwnProperty 方法来区分对象的成员是明智的:

1
2
3
4
5
for (variable in object) {
if (object.hasOwnProperty()) {
statements;
}
}

while 语句

while 语句应该使用如下格式:

1
2
3
while (condition) {
statements;
}

do 语句

do 语句应该使用如下格式:

1
2
3
do {
statements;
} while (condition);

不像其它复合语句,do 语句始终使用“;”(分号)结尾。

switch 语句

switch 语句应该有如下格式:

1
2
3
4
5
6
7
switch (expression) {
case expression:
statements;
break;
default:
statements;
}

每组语句(除了 default)应该以 break,return 或者 throw 结束。不要 fall through。

try 语句

try 语句应该使用如下格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
try {
statements;
} catch (variable) {
statements;
}
#
try {
statements;
} catch (variable) {
statements;
} finally {
statements;
}

continue some 语句

不要使用 continue some;语句。它会让方法的控制流程模糊。

with 语句

不要使用 with 语句。

this

仅在对象构造器, 方法, 闭包中使用.
this 的语义很特别. 有时它引用一个全局对象(大多数情况下), 调用者的作用域(使用 eval 时), DOM 树中的节点(添加事件处理函数时), 新创建的对象(使用一个构造器), 或者其他对象(如果函数被 call() 或 apply()).
使用时很容易出错, 所以只有在下面两个情况时才能使用:

  • 在构造器中
  • 对象的方法(包括创建的闭包)中
  • toString() 方法
    应该总是成功调用且不要抛异常.
    可自定义 toString() 方法, 但确保你的实现方法满足: (1) 总是成功 (2) 没有其他负面影响. 如果不满足这两个条件, 那么可能会导致严重的问题, 比如, 如果 toString() 调用了包含 assert 的函数, assert 输出导致失败的对象, 这在 toString() 也会被调用.

5. 函数

属性和方法

  • 文件或类中的 私有 属性, 变量和方法名应该以下划线 “_“ 开头.
  • 保护 属性, 变量和方法名不需要下划线开头, 和公共变量名一样.
    更多有关 私有 和 保护的信息见, visibility.

方法和函数参数

可选参数以 opt_ 开头.
函数的参数个数不固定时, 应该添加最后一个参数 var_args 为参数的个数. 你也可以不设置 var_args 而取代使用 arguments.
可选和可变参数应该在 [@param ] 标记中说明清楚. 虽然这两个规定对编译器没有任何影响, 但还是请尽量遵守

Getters 和 Setters

Getters 和 setters 并不是必要的. 但只要使用它们了, 就请将 getters 命名成 getFoo() 形式, 将 setters 命名成 setFoo(value) 形式. (对于布尔类型的 getters, 使用 isFoo() 也可.)

命名空间

  • JavaScript 不支持包和命名空间.
    不容易发现和调试全局命名的冲突, 多个系统集成时还可能因为命名冲突导致很严重的问题. 为了提高 JavaScript 代码复用率, 我们遵循下面的约定以避免冲突.
  • 为全局代码使用命名空间
    在全局作用域上, 使用一个唯一的, 与工程/库相关的名字作为前缀标识. 比如, 你的工程是 “Project ixdcw”, 那么命名空间前缀可取为 ixdcw.*.
1
2
3
4
var ixdcw = {};
ixdcw.sleep = function() {
...
};

明确命名空间所有权
当选择了一个子命名空间, 请确保父命名空间的负责人知道你在用哪个子命名空间, 比如说, 你为工程 ‘sloths’ 创建一个 ‘hats’ 子命名空间, 那确保 Sloth 团队人员知道你在使用 sloth.hats. 外部代码和内部代码使用不同的命名空间
“外部代码” 是指来自于你代码体系的外部, 可以独立编译. 内外部命名应该严格保持独立. 如果你使用了外部库, 他的所有对象都在 foo.hats.* 下, 那么你自己的代码不能在 foo.hats.*下命名, 因为很有可能其他团队也在其中命名.

6. 额外的建议

{}和[]

使用{}替代 new Object()。使用[]替代 new Array()。
当成员名字为连续的整数时使用数组。当成员名字为任意的字符串或名字时使用对象。
使用 Array 和 Object 语法, 而不使用 Array 和 Object 构造器.

1
2
3
4
5
6
7
8
9
10
11
var a  = [x1, x2, x3];
var a2 = [x1, x2];
var a3 = [x1];
var a4 = [];
var o = {};
var o2 = {
a: 0,
b: 1,
c: 2,
'strange key': 3
};

逗号操作符

不要使用逗号操作符,除了 for 语句的控制部分的严格使用。(这不适合逗号操作符,它应该用于对象字面量,数组字面量,var 语句和参数列表。

块作用域

在 JavaScript 里块没有作用域,只有方法有作用域。不要使用块,除了复合语句一定需要用到外。

赋值表达式

不要在 if 和 while 语句的条件部分做赋值。不要写不易懂的代码。

===和!==操作符

始终使用===和!==操作符会更好。和!=操作符会做类型强制转换。特别是,不要使用来和“假”值做比较。

令人混淆的加和减

注意不要在“+”后面跟“+”或“++”。这种模式令人混淆。在它们之间插入圆括号来让你的意图更清晰。

1
2
3
total = subtotal + +myInput.value;
// is better written as
total = subtotal + (+myInput.value);

这样“+ +”就不会被读错成“++”。

只用于解析序列化串 (如: 解析 RPC 响应)

eval 方法是 JavaScript 里最滥用的特性。不要使用它。
解析序列化串是指将字节流转换成内存中的数据结构. 比如, 你可能会将一个对象输出成文件形式:

1
2
3
4
5
6
7
8
9
10
11
12
13
users = [
{
name: 'Eric',
id: 37824,
email: 'jellyvore@myway.com'
},
{
name: 'xtof',
id: 31337,
email: 'b4d455h4x0r@google.com'
},
...
];

很简单地调用 eval 后, 把表示成文件的数据读取回内存中.
类似的, eval() 对 RPC 响应值进行解码. 例如, 你在使用 XMLHttpRequest 发出一个 RPC 请求后, 通过 eval () 将服务端的响应文本转成 JavaScript 对象:

1
2
3
4
5
6
7
8
9
10
11
var userOnline = false;
var user = 'nusrat';
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', 'http://chat.google.com/isUserOnline?user=' + user, false);
xmlhttp.send('');
// Server returns:
// userOnline = true;
if (xmlhttp.status == 200) {
eval(xmlhttp.responseText);
}
// userOnline is now true.

其他

不要使用 Function 构造函数。
不要传递字符串给 setTimeout 或者 setInterval。

JSDoc

  • 普通类型 {boolean}, {Window}, {goog.ui.Menu}

普通类型的描述方法.

  • 复杂类型

参数化类型, 即指定了该类型中包含的一系列”类型参数”. 类似于 Java 中的泛型.

  • 字符串数组{Array.<string>}
  • 键为字符串, 值为整数的对象类型 {Object.<string, number>}
  • 联合类型 {(number|boolean)}

一个整数或者布尔值. 表示其值可能是 A 类型, 也可能是 B 类型

  • 记录类型 {myNum: number, myObject}

由现有类型组成的类型. 表示包含指定成员及类型的值. 这个例子中, myNum 为 number 类型, myObject 为任意类型.
注意大括号为类型语法的一部分. 比如, Array.<{length}>, 表示一具有 length 属性的 Array 对象.

  • 可为空类型 {?number}

一个整型数或者为 NULL 表示一个值可能是 A 类型或者 null. 默认, 每个对象都是可为空的. 注意: 函数类型不可为空.

  • 非空类型 {!Object}

一个对象, 但绝不会是 null 值. 说明一个值是类型 A 且肯定不是 null. 默认情况下, 所有值类型 (boolean, number, string, 和 undefined) 不可为空.

  • 函数类型 {function(string, boolean)}

具有两个参数 ( string 和 boolean) 的函数类型, 返回值未知. 说明一个函数.

  • 函数返回类型 {function(): number}

函数返回一个整数. 说明函数的返回类型.

  • 函数的 this 类型 {function(this:goog.ui.Menu, string)}

函数只带一个参数 (string), 并且在上下文 goog.ui.Menu 中执行. 说明函数类型的上下文类型.

  • 可变参数 {function(string, ...[number]): number}

带一个参数 (字符类型) 的函数类型, 并且函数的参数个数可变, 但参数类型必须为 number. 说明函数的可变长参数.
可变长的参数 (使用 [@param ] 标记) [@param ] {…number} var_args
函数参数个数可变. 使用标记, 说明函数具有不定长参数.

  • 函数的 缺省参数 {function(?string=, number=)}

函数带一个可空且可选的字符串型参数, 一个可选整型参数. = 语法只针对 function 类型有效. 说明函数的可选参数.
函数 可选参数(使用 [@param ] 标记) [@param ] {number=} opt_argument
number 类型的可选参数. 使用标记, 说明函数具有可选参数.

  • 所有类型 {*}

表示变量可以是任何类型.

JS 类型

  • number

Number new Number(true) Number 对象

1
2
3
4
5
1
1.0
-5
1e5
Math.PI
  • string

字符串对象

1
2
3
4
5
'Hello'
"World"
String(42) # 字符串值
String new String('Hello')
new String(42)
  • boolean

布尔对象

1
2
3
4
5
true
false
Boolean(0) 布尔值
Boolean
new Boolean(true)
  • RegExp
1
2
new RegExp('hello')
/world/g
  • Date
1
2
new Date
new Date()
  • null
1
null
  • undefined
1
undefined
  • void
1
2
3
function f() {
return;
}
  • Array
1
2
3
4
5
6
7
['foo', 0.3, null]
# 类型不明确的数组
[]
# Array.<number>
[11, 22, 33] # 整型数组
# Array.<Array.<string>>
[['one', 'two', 'three'], ['foo', 'bar']] #字符串数组的数组
  • Object
    注意, JavaScript 中, 键总是被转换成字符串, 所以 obj[‘1’] == obj[1]. 也所以, 键在 for…in 循环中是字符串类型. 但在编译器中会明确根据键的类型来查找对象.
1
2
3
4
5
{}
{foo: 'abc', bar: 123, baz: null}
Object.<string> {'foo': 'bar'} 值为字符串的对象.
Object.<number, string> var obj = {};
obj[1] = 'bar'; 键为整数, 值为字符串的对象.
  • Function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function(x, y) {
return x * y;
} 函数对象
function(number, number): number function(x, y) {
return x * y;
} 函数值
SomeClass /** @constructor */
function SomeClass() {}
#
new SomeClass();
SomeInterface /** @interface */
function SomeInterface() {}
#
SomeInterface.prototype.draw = function() {};
project.MyClass /** @constructor */
project.MyClass = function () {}
#
new project.MyClass()
project.MyEnum /** @enum {string} */
project.MyEnum = {
BLUE: '#0000dd',
RED: '#dd0000'
};
  • Element
    DOM 中的元素
1
document.createElement('div')
  • Node
    DOM 中的节点
1
document.body.firstChild
  • HTMLInputElement
    DOM 中, 特定类型的元素.
1
htmlDocument.getElementsByTagName('input')[0]

函数定义规范及说明

  • 内置函数采用下划线前缀命名
  • 函数传入的参数使用下划线命名
  • 内部定义的参数使用驼峰方式命名
  • jQuery 选择器调用元素的获取使用 $ 作为前缀
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 参数是下划线分隔
exports.countdown = function (btn_selector, str, time, end_str) {
// 按钮jquery 选择器使用 `$`
var $btn = $(btn_selector);
// 这里是驼峰命名
var countdownHandler = setInterval(_countdown, 1000);
// ...
function _countdown() {
var count_str = str.replace(/\{time\}/, count);
$btn.text(count_str);
if (count == 0) {
$btn.text(displayStr).removeAttr("disabled");
clearInterval(handlerCountdown);
}
count--;
}
// ...
};
  • 代码完成之后不得留有调试代码。
  • js 编写注意性能优化,如获取两次,调用两次可更正为获取一次,调用两次。
  • 插件中展示的内容尽量不用 table 标签( table 标签存在局限性),应用 ul 代替.
  • 功能函数前必须添加注释,注释函数功能。
  • 语句结束必须有‘;’。
  • if,else 执行语句用花括号‘{}’包裹起来。
  • 自编插件注意配置项的必选配置,需判断是否传入。

Web 编码规范 v3.0

本文规范合并 html/css 规范

文件及格式化

文件编码为 utf-8

更多 UTF-8 内容: http://zh.wikipedia.org/zh/UTF-8

使用 空格 进行缩进

使用 4 空格缩进来表明嵌套层次

网页大小

“网页大小”定义为网页的所有文件大小的总和,包括 HTML 文件和所有的嵌入的对象。用户喜欢快的而不是新奇的站点。网页主体加载速度控制在 3S 以内

注释

注释适用部分参考 公共约定

Html 部分

全局定义

DOCTYPE

页面文档类型统一使用 HTML5 DOCTYPE, 为每个 HTML 页面添加标准模式(standard mode)的声明,确保在每个浏览器中拥有一致的展现

1
<!doctype html>

字符集设置

声明方法遵循 HTML5 的规范, Meta 文件使用 “UTF-8” 浏览器显示编码指定, 通过声明一个明确的字符编码,让浏览器轻松、快速的确定网页内容渲染方式,通常指定为’UTF-8’

1
2
3
4
5
6
<html>
<head>
<meta charset="UTF-8" />
</head>
...
</html>

语言属性

为每个 HTML 页面根元素添加 lang 属性

根据 HTML5 规范:

强烈建议为 html 根元素指定 lang 属性,从而为文档设置正确的语言。这将有助于语音合成工具确定其所应该采用的发音,有助于翻译工具确定其翻译时所应遵守的规则等等。

1
2
3
<html lang="zh-CN">
<!-- ... -->
</html>

引入 CSS 和 JavaScript 文件

根据 HTML5 规范,在引入 CSS 和 JavaScript 文件时不需要指定 type 属性,因为 text/csstext/javascript 分别是它们的默认值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- External CSS -->
<link rel="stylesheet" href="code_guide.css" />

<!-- In-document CSS -->
<style>
...;
</style>

<!-- External JS -->
<script src="code_guide.js"></script>

<!-- In-document JS -->
<script>
...
</script>

语法

特殊符号使用 HTML 字符实体(实体名称对大小写敏感)

常用如下:

符号 实体编码
空格 &nbsp;
© &copy;
¥ &yen;
® &reg;
> &gt;
< &lt;
& &amp;

td / th 要在 tr 里面,li 要在 ul / ol 里面

1
2
3
4
5
6
7
8
9
10
11
<!-- not good -->
<table>
<td>test</td>
</table>

<!-- good -->
<table>
<tr>
<td>test</td>
</tr>
</table>

ul / ol 的直接子元素只能是 li,不能包含其他元素

1
2
3
4
5
6
<!-- not good -->
<ul>
<span>123</span>
<li>a</li>
<li>b</li>
</ul>

行内元素里面不可使用块级元素

a 标签是一个行内元素,行内元素里面套了一个 div 的标签,这样可能会导致 a 标签无法正常点击

1
2
3
4
<!-- not good -->
<a href="../test">
<div></div>
</a>

可以使用如下代码进行修复:

1
2
3
<a href="../test" style="display: block">
<div></div>
</a>

不使用重复属性,重复的属性只会取第一个

1
2
3
4
5
<!-- error -->
<input class="a" type="text" class="b" />

<!-- good -->
<input class="a b" type="text" />

不要在 https 的链接里写 http 的图片

只要 https 的网页请求了一张 http 的图片,就会导致浏览器地址栏左边的小锁没有了,一般不要写死,写成根据当前域名的协议去加载,用//开头:

1
<img src="//static.chimeroi.com/hello-world.jpg" />

不要在自闭合(self-closing)元素的尾部添加斜线

HTML5 规范中说明这是可选的)

1
2
3
4
5
<!-- not good -->
<img src="logo.png" alt />

<!-- good -->
<img src="logo.png" alt />

不使用属性设置样式(img, table等元素)

1
2
3
4
5
<!-- not good -->
<img src="test.jpg" alt width="400" height="300" />

<!-- good -->
<img src="test.jpg" style="width:400px;height:300px;" />

自定义属性要以 data-开头

自己添加的非标准的属性要以 data-开头,否则w3c validator会认为是不规范的

1
2
3
4
5
<!-- not good -->
<div count="5"></div>

<!-- good -->
<div data-count="5"></div>

使用尽可能少的元素/嵌套

由于元素嵌套越多会是的浏览器解析速度出现问题, 所以规定元素嵌套不要超过六级, 尽量遵循 HTML 标准和语义,但是不要以牺牲实用性为代价;任何时候都要尽量使用最少的标签并保持最小的复杂度。

尽量避免多余的层级

1
2
3
4
5
6
7
<!-- not good -->
<span class="avatar">
<img src="..." />
</span>

<!-- good -->
<img class="avatar" src="..." />

兼容性

代码使用 html5 标准代码编写文档, 并且 ie8+, firefox, chrome 做到兼容, 禁止使用不兼容的标签,附录中包含了 html5 不支持的代码和新增的代码,这些标签禁止使用.
禁止使用特殊的标签

协议

如果链接和当前页面一致则忽略链接的协议部分, 建议在指向图片或其他媒体文件、样式表和脚本的 URL 地址中省略 http:, https:协议部分

1
<script src="//www.taobao.com/fp.js">

语义

使用符合语义的标签书写 HTML 文档, 选择恰当的元素表达所需的含义;

1
2
3
<a href="recommendations/">
All recommendations
</a>

大小写

元素的标签和属性名必须小写, 属性值必须加双引号;

1
<a href="/">Home</a>

属性应该按照特定的顺序出现以保证易读性

  1. class
  2. id
  3. name
  4. data-*
  5. src, for, type, href, value , max-length, max, min, pattern
  6. placeholder, title, alt
  7. aria-*, role
  8. required, readonly, disabled

空格

去除不必要的空格

1
2
3
4
# Bad
<p>test </p>
# Good
<p>test</p>

嵌套和闭合

元素嵌套遵循 (X)HTML Strict 嵌套规则, 推荐使用 Firefox 插件 HTML Validator 进行检查;
正确区分自闭合元素和非自闭合元素.
非法闭合包括:<br>..</br>、<script />、<iframe />, 非法闭合会导致页面嵌套错误问题
自闭和标签: 以下元素不要求闭合, 原因见: HTML(5) 不要求标签自闭合
非闭合标签:area, base, br, col, command, embed, hr, img, input, keygen, link, meta, param, source, track, wbr

引号

使用双引号来标识 html 的属性

1
2
3
4
5
6
7
8
9
# Bad
<a class='maia-button maia-button-secondary'>
Sign in
</a>

# Good
<a class="maia-button maia-button-secondary">
Sign in
</a>

自定义 javascript 属性

通过给元素设置自定义属性来存放与 JavaScript 交互的数据, 属性名格式为 data-xx (例如:data-lazyload-url)

1
<div class="bg bg-4"  data-load="false"></div>

目的是使用 js 调用时候对元素进行识别使用.

TODO

使用 TODO 来标记待做事情,便于后期搜索.
在 TODO 后添加 (姓名或邮件) 来表示分类

1
2
<!-- TODO(Mark Zhao): remove duplicate tag -->
<p><span>2</span></p>

焦点分离

将表现,行为和结构分离:不要在 html 和模板中加入除了结构以外的东西.例如内联样式, center 等标记.
在文档中引入尽可能少的样式和脚本

1
2
3
4
5
6
7
8
9
10
# Bad
<h1 style="font-size: 1em;">HTML sucks</h1>
<p>I've read about this on a few sites but now I'm sure:<u>HTML is stupid!!1</u><center>I can't believe there's no way to control the styling of my website without doing everything all over again!</center><p>

# Good
<h1>My first CSS-only redesign</h1>
<p>I've read about this on a few sites but today I'm actually
doing it: separating concerns and avoiding anything in the HTML of
my website that is presentational.
<p>

block,list 或 table 元素

针对每个 block,list 或 table 元素另起一行,并在每个子元素前缩进。这样可读性好

1
2
3
4
5
6
<ul>
<li>some list file</li>
...
</ul>
# ~
<table></table>

Table 的写法

  • </td> 结束标记应该与 <td> 处于同一行,不要换行, 如果换行,浏览器将会解析内容为内容+半角空格.
  • 不允许任何没有内容的空单元格存在,空单元格中必须存在
  • 表格高度和宽度的控制, 不出现多于一个的控制同一个单元格大小的 height 和 width, 保证任何一个 width 和 height 都是有效的,也就是你改动代码中任何一个 width 和 height 的数值,都应该在浏览器中看到变化
  • 一般情况下只有一列的表格,width 写在 <table> 的标签内
  • 只有一行的表格,height 写在 <table> 的标签内
  • 多行多列的表格,width 和 height 写在第一行或者第一列的 <td> 标签内
  • 尽量避免 colspan, rowspan 两个属性

实体字符

html 标签<, >、空格、特殊符号需要使用 html 实体

SEO 优化

  • a 元素必须加 title=""
  • img元素必须加 alt = ""
  • [ie7] button 参数必须带有 type=”submit” , 否则表单不会提交

注释

建议对超过一屏的代码页面模块进行注释, 以降低开发人员的嵌套成本和后期的维护成本.

1
2
3
4
5
<div id="sample">
<div class="someCategory">
...
</div><!-- .someCategory End -->
</div><!-- #sample End -->

Js 协作

Js 调用的 html 数据

使用 data- 作为前缀

事件驱动

使用事件驱动 js 事件, 不需要写 onclick="function" 而是采用 require 方式调用

id

html 中的 id 仅仅作为js句柄调用, 仅仅用于调用事件驱动, 不作为样式定义使用

Css 部分

此部分的约定包含 less, sass 等预编译的约定

项目文件规范

  • 左大括号放置在类的末尾
  • 修改的重要的注释使用以下来进行注释, 其余采用简洁注释

命名

文件命名

  • 文件使用小写/中杠线命名
  • 文件根据模块的名称来进行命名
  • 禁止使用拼音

类命名/模块嵌套

  • 禁止使用拼音
    命名格式是为了规范网站中样式命名混乱的问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 大区域命名
{$project}--{$component} {
// 小区域命名
{$component}-{$block}
}

$project(项目), $component(部件), $block(区块)
样式均不能包含 '--'(双中杠线), '-'(单中杠线)
样式建议使用小写字母标识, 尽量不要包含数字
-- 作为大区块分割线
- 作为小区块分割线


例如 fe 作为整个前端项目的标识

fe--editor : 为编辑器的命名
editor-top : 编辑器顶部命名
editor-footer : 编辑器底部命名
这里的
$project : fe
$component : editor
$block : [top, footer, ...]

html 代码

1
2
3
4
5
<div class="fe--editor">
<div class="editor-top"></div>
...
<div class="editor-footer"></div>
</div>

资源命名

文件夹中的资源图片名称和 文件 名称对应起来
例如是个人资料文件是 user.less, 这个资源应该放到指定资源目录的 user 文件夹中.

1
2
3
4
┝ user.less
┕ user # 文件夹
┝ ...
┕ header.png

less 中的变量、函数、mixin 等采用驼峰式命名

对于变量的命名采用(定义/模块) 来进行命名, 使用中尽量不要直接调用颜色, 而是调用模块的定义

1
2
3
4
5
6
7
8
9
@mainFontColor: #444;

:root {
--mod-border-color: @mainFontColor;
}

.mod {
color: var(--mode-border-color);
}

常用的标示符

1
2
3
4
5
# 大小
-xs # extreme small
-sm # small
-lg # large
-xl # extreme large

语法

所有声明语句都应当以分号结尾

最后一条声明语句后面的分号是可选的,但是,如果省略这个分号,你的代码可能更易出错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* error */
.selector {
font-size: 15px
color: red
}

/* not good */
.selector {
font-size: 15px;
color: red
}

/* good */
.selector {
font-size: 15px;
color: red;
}

为选择器分组时,将单独的选择器单独放在一行

1
2
3
4
5
6
/* good */
.selector,
.selector-secondary,
.selector[type="text"] {
/* ... */
}

避免为 0 值指定单位

例如,用 margin: 0; 代替 margin: 0px;

  1. 为选择器中的属性添加双引号,例如,input[type="text"]
    某些情况下是可选的,但是,为了代码的一致性,建议都加上双引号

    1
    2
    3
    4
    5
    6
    7
    8
    9
    /* not good */
    .selector[type="text"] {
    /* ... */
    }

    /* good */
    .selector[type="text"] {
    /* ... */
    }
  2. 十六进制值应该全部小写,例如,#f3f6fa

  3. 不出现空的规则(声明块中没有声明语句)

  4. 不要设置太大的 z-index(一个正常的系统的层级关系在 10 以内就能完成)

  5. 多写注释,且多使用句子进行描述而不是词语

    1
    2
    3
    4
    5
    /* 为了去除输入框和表单点击时的灰色背景 */
    input,
    form {
    -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
    }
  6. 不要使用*选择器

  7. 适当使用:before:after来画页面的一些视觉上的辅助性元素,如三角形、短的分隔线、短竖线等,可以减少页面上没有用的标签

  8. 选择器不要超过 4 层(在 Less 中避免嵌套超过 4 层)

  9. border: 0; 代替 border: none;

  10. 使用简写形式的十六进制值,例如,用 #fff 代替 #ffffff

  11. 对于属性值或颜色参数,省略小于 1 的小数前面的 0 (例如,.5 代替 0.5-.5px 代替 -0.5px

写法技巧

样式定义可以覆盖公共样式

1
2
3
4
# a 是公共样式, 这里写的样式会覆盖掉公共样式
.my--profile a{
...;
}

元素嵌套级别不超过 6 级

  • js 调用的样式 J_xxxx 字母 J 加下滑线 _ ,并且不要将这些 class 包含到 CSS 文件中。

id 不能写 css 样式

由于 id 属性作为仅仅作为 js 来调用, 所以使用到 JS 调用 class 的时候使用 J_ 作为调用的句柄

1
2
3
4
5
<script>
$('.J_tabs').hover(function(){
...;
})
</script>

logo 最好和 h1 标题使用一个

logo 用背景图标来显示, 必须用“h1”来标识。 .head h1{}

空行

成组的 css 规则使用空行来分隔. 多分组使用多空行来分隔

love/hate 写法

a 标签采用 LOVEHATE 写法

l(link)ov(visited)e h(hover)a(active)te

1
2
3
4
a:link{}
a:visited{}
a:hover{}
a:active{}

混排时候的字体定义

中英文混排时,我们尽可能的将英文和数字定义为 verdana 和 arial 两种字体

这样为了避免字符使用宋体时候出现的各种问题
会将人民币符号(两横)表现成日元的符号(一横)等问题
宋体表现数字和字母不协调

字体字号

一般使用中文宋体 12px 和 14.7px 这是经过优化的字号,黑体字或者宋体字加粗时,一般选用 11pt 和 14.7px 的字号比较合适

尽量使用简写属性

这里 0 不需要单位, 对属性值为 0 的情况省略单位

1
2
3
.col-main .content{
padding: 0 1em 2em
}

元素的隐藏

  • display:none隐藏对象浏览器不作渲染,不占用内存。而visibility:hidden则会

对于隐藏元素使用 display:none

颜色使用 16 进制表示

颜色使用 16 进制的值表示

引号

尽可能不使用引号, 迫不得已使用单引号 '

css 精灵

合理使用 CSS Sprite, 并控制质量和文件大小

对图片大小进行优化
RIOT : 图片压缩工具

公共样式

宽度分组, 宽度用 w 前缀表示, 尽量不要定宽

从 w120 开始, 一直写到 12px - 720px 宽度使用 12px 作为步进

1
2
3
.w12{width:12px;}
...
.w720{width:720px;}

位置及监听

css 文件不需要自己去手动创建, 而是使用 compass, sass 来生成并且维护 css 样式

  1. 声明块的左花括号前添加一个空格

  2. 声明块的右花括号应当单独成行

  3. 每条声明语句的 : 后应该插入一个空格

  4. 每条样式声明应该独占一行

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    /* not good */
    .selector {
    font-size: 15px;
    color: red;
    }

    /* good */
    .selector {
    font-size: 15px;
    color: red;
    }
  5. 对于以逗号分隔的属性值,每个逗号后面都应该插入一个空格(例如,box-shadowtransition

    1
    2
    3
    4
    5
    6
    7
    8
    9
    /* not good */
    .selector {
    transition: border 0.2s, color 0.3s, padding 0.4s;
    }

    /* good */
    .selector {
    transition: border 0.2s, color 0.3s, padding 0.4s;
    }
  6. !important前插入一个空格

  7. 注释://后插入一个空格,/*后插入一个空格,*/前插入一个空格

  8. Less 的操作符,在圆括号中的数学计算表达式的数值、变量和操作符之间均添加一个空格

  9. 注释统一用/* */( Less 中也不要用//

样式兼容性

  1. 当使用一些较新的 CSS3 语法时,应注意添加浏览器前缀( FAIS 2 打包工具包含 CSS 预处理,固无需考虑此条)

  2. 不要使用 input 的 line-height 来做垂直居中
    设置 line-height 为一个很高的值会导致 Safari 浏览器的输入光标变得巨大 (与 line-height 等高)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /* not good */
    input {
    height: 40px;
    line-height: 40px;
    }

    /* good */
    input {
    height: 20px;
    line-height: 20px;
    padding: 10px 0;
    }

选择器权重(样式覆盖)

权重的基本规则:

  1. 相同的权重:以后面出现的选择器为最后规则
  2. 不同的权重,权重值高则生效

详细了解权重计算方法

  1. 非通用样式使用嵌套方式进行编写,避免影响其他自己不了解样式,造成样式覆盖
  2. Vue 中样式谨慎使用 scoped,会影响样式选择器性能,请使用第一点进行特有样式编写
  3. 样式需要修改时,尽量找到原样式声明进行修改
  4. 无法修改原样式声明时,应通过权重关系,编写权重更高的样式进行覆盖
  5. 不使用!important,除非原样式使用内联样式或!important且无法直接修改

声明简写

  1. 当你不确定自己写的属性会否影响到其他属性时,应避免使用简写

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    /* error */
    .element {
    margin: 0 0 10px;
    background: red;
    background: url("image.jpg");
    border-radius: 3px 3px 0 0;
    }

    /* good */
    .element {
    margin-bottom: 10px;
    background-color: red;
    background-image: url("image.jpg");
    border-top-left-radius: 3px;
    border-top-right-radius: 3px;
    }
  2. 当你确定自己的声明不会影响到其他属性时,请使用简写提升代码简洁性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /* not good */
    .element {
    padding-top: 10px;
    padding-right: 20px;
    padding-bottom: 15px;
    padding-left: 20px;
    }

    /* good */
    .element {
    padding: 10px 20px 15px;
    }

CSS 动画

  1. 不要使用 all 属性做动画

使用 transition 做动画的时候不要使用 all 所有属性,在有一些浏览器上面可能会有一些问题,如下:

1
transition: all 2s linear;

在 Safari 上面可能会有一些奇怪的抖动,正确的做法是要用哪个属性做动画就写哪个,如果有多个就用隔开,如下代码所示:

1
transition: transform 2s linear, opacity 2s linear;
  1. 位移动画使用 transform 替代 position (提升动画性能)
  2. 使用 CSS 动画替代 JS 动画

声明顺序

相关的属性声明按以下顺序做分组处理,组之间需要有一个空行

  1. Positioning(影响其他元素和自身位置相关声明)

  2. Box model(自身盒模型相关声明)

  3. Typographic(文本相关声明)

  4. Visual(自身样式)

  5. Misc(其他声明)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    .declaration-order {
    /* Positioning */
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 100;

    /* Box-model */
    display: block;
    float: right;
    width: 100px;
    height: 100px;

    /* Typography */
    font: normal 13px "Helvetica Neue", sans-serif;
    line-height: 1.5;
    color: #333;
    text-align: center;

    /* Visual */
    background-color: #f5f5f5;
    border: 1px solid #e5e5e5;
    border-radius: 3px;

    /* Misc */
    opacity: 1;
    }

附录

v3.0(2021-11-12)

  • 合并 html / css 规范
  • 移除对 IE 的支持

v2.0(2017-08-26)

Android 开发 - 岗位职责\_评级

岗位职责

  • 负责 Android 手机客户端软件的设计及开发,根据项目的具体要求,完成任务目标
  • 负责工程中主要功能的代码实现,调试及后期维护
  • 负责根据其他开发组提供的数据接口进行数据交互
  • 负责编制 Android 项目相关的技术文档
  • 完成 Android 项目的日常升级,解决测试,领导提交的 bug 和改进建议
  • 协助测试人员完成软件的测试
  • 负责软件集成,部署,发布等工作
  • 严格遵守相关开发工具的编码规范,优化代码
  • 与其他员工合作开发,共同进行产品的开发,维护以及测试
  • 对 Android 项目进行版本控制及分支管理
  • 配合领导管理,完成领导安排的其他临时任务, 遵守公司相关制度

岗位要求

岗位评级

见习工程师

Title : 实习生(student engineer)

[1500-3000]

  1. 掌握基本的 Android 应用开发和调试技能,了解 Android SDK,会用 Eclipse,AS 等开发工具;
  2. 掌握基础控件、UI 布局,能够处理多分辨率适配;
  3. 具有较强的团队协作精神及高度的责任心,会使用 SVN,GIT 等协同开发工具;
  4. 了解面向对象编程思想,了解 MVC、MVP、MVVM,了解 JSON、XML 等数据解析。

补充:

可以写出 UI 界面,完成基本需求功能,会用开源框架以及开源控件,甚至会改造成符合自己项目的,了解一些 android 源码,但是知识面比较单一,懂数据结构,设计模式,计算机网络(OSI7 层模型每一层),数据库,服务器,熟练各大开源库,熟悉 Git,会造些轮子,会翻阅 android 源码,会逛各大技术网站,对新技术敏感(RxJava,Retrofit,Dagger,MVP,kotlin……),会反编译去研究别人 APP。

完全掌握 View 绘制过程,消息处理机制,事件分发机制,进程间通讯,NDK 开发。有一些不错的作品。

初级工程师

Title : 菜鸟(junior engineer)

[3000-5000]

  1. 熟悉 Android 平台下 GUI 设计和实现;
  2. 能够熟练配置 Android 开发环境, 有 1 年以上 Android 开发经验
  3. 具备扎实的 java 基础;熟练掌握 B/S、C/S 开发,有实际项目经验;
  4. 对数据结构、基本算法熟练掌握,并具备基本的算法设计能力;
  5. 优秀的文档编写和语言表达能力,良好的中英文阅读水平;
  6. 必须具备良好的编程习惯;对待工作认真负责,有较强独立解决问题的能力。

中级工程师

Title : 大虾(intermediate engineer)

[5000-7000]

  1. 对各种系统版本和机器适配有充分的经验
  2. 熟悉性能调优,崩溃处理
  3. 熟悉 UI 表现和用户体验
  4. 理解框架和背后的设计,而不是简单的 API 堆砌
  5. 对 UI 控件有丰富经验,包括自绘控件和动画
  6. 扎实的编程功底,能享受编程乐趣
  7. 高效的学习能力和分析解决问题能力

2 年以上 android 开发经验

写一些项目中要用的自定义控件,并优化出部分功能集成到工具类,能把控整体项目架构,搭出基本框架,可能耦合性高,扩展性不抢,看懂过 android 部分源码,知识面比较广。

高级工程师

Title : 大牛/专家(senior engineer)

[7000-9000]

  1. 熟悉 Android OS 系统体系结构、framework 层;
  2. 良好的 Java 技术功底,精通多线程、socket 通信、文件操作等 java 底层技术;
  3. 精通 Android 的基本组件使用,熟练使用 Android 各种布局与控件,熟练运用各种动画特效;
  4. 熟悉 View 的绘制原理,精通自定义动画以及自定 View 的开发,熟悉常用组件和框架的实现原理
  5. 有丰富的 Android 性能优化经验,善于解决系统崩溃,内存溢出和兼容性问题;
  6. 熟悉 JNI 技术和代码混淆
  7. 有单元测试、自动化测验及相关框架经验;
  8. 有良好的代码习惯,要求结构清晰,命名规范,逻辑性强,代码冗余率低,代码注释清晰;
  9. 对新技术有一定的创新和优化能力

本科或以上学历,计算机软件相关专业;

3 年以上 Android 开发经验;

搭项目框架,解耦,扩展性强,造专业的轮子,优化程序性能,掌握些黑科技,研究 android 源码,知识面设计广而深

架构师

Title: 大神/骨灰(android architect)

[9000 以上]

  1. 精通 Java 平台开发,熟悉面向对象设计方法和常用设计模式;
  2. 精通 Android 框架,深入了解底层服务、Binder IPC、SurfaceFlinger 等技术;
  3. 精通 Android UI 布局开发/Animation/OpenGL|ES/Multimedia 开发技术;
  4. 有丰富的软件架构设计经验,能快速搭建、调试或重构大规模软件代码;
  5. 掌握 JNI 技术,能熟练使用 Android SDK,能独立进行应用程序开发和移植;
  6. 精通 Android 多线程,对 HTTP/HTTPS/TCP/Socket 等网络通信协议有深刻理解和经验;
  7. 有足够的软件安全意识,掌握数据加密、代码混淆、防破解、性能优化等技术;

掌握两种以上开发语言或开发平台、全栈等技能

对新技术领域有较强的探索性研究能力

可根据实际需要加入学历,开发年限等附加条件

PHP 命名规范(Laravel 增补版)

代码风格统一

phpstorm 常用快捷键

1
2
3
4
ctrl/cmd + alt + L          # 格式化代码
ctrl/cmd + alt + O       # 项目 use 优化 / 优化导入
ctrl/cmd + shift + n       # 查找文件
ctrl/cmd + alt + shift + n # 查找函数

代码推送

master : 线上分支 develop : 开发分支

任何人不得直接在这两个分支进行开发, 开发完毕后将代码用 pr
的方式提交合并请求, 由 pr 负责人审核完成后才能够合并到 develop 分支或者
master 分支

单元测试

必须对接口写单元测试, 否则测试不通过的代码一律打回

参数传递

(一般情况下来讲)类函数少于或者等于 4 个参数的, 可以直接使用参数传递

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// before
public function beChid($data): bool
{
$account_id = data_get($data, 'account_id');
$initDb = [
'account_id' => $account_id,
'chid_status' => array_get($data, 'status'),
'chid_failed_reason' => array_get($data, 'reason') ?? '',
];
}

// after
public function beChid($account_id, $status, $reason = ''): bool
{
$initDb = [
'account_id' => $account_id,
'chid_status' => $status,
'chid_failed_reason' => $reason,
];
}

数据管理方式

  1. 本地数据库每日备份一次
  2. 线上数据库使用策略等方式, 每日备份一次
  3. 数据库采用独立服务器
  4. 软件服务器和数据库服务器分开请求, 不得走一个服务器,
    便于数据库独立分开
  5. 本地开发使用图片服务器进行图片的存储上传

数据模型

  • 注释
  • 报错
  • 数据库调用最小化

[原] 在 PhpStorm 中使用 Xdebug 远程调试 PHP 程序(框架/原生均适用)

序言

Xdebug 作为 PHP 调试工具,提供了丰富的调试函数和配置,可以直观的看到 PHP 源代码的步进和性能数据,以便优化 PHP 代码。

使用 phpstorm + xdebug 来调试 php 程序是借助强大的 IDE 监听功能, 更方便的调试程序. 提高我们的编码效率, 固然 var_dump, print_r 等函数也能提供相应的功能, 但是自动化的工具更能够事半功倍. 下面我根据自己的使用介绍下如何进行调试和配置.

一种方式是用外部设置的 session, 另外一种是在 phpstorm 中配置页面入口然后使用内置的监听来访问, 原理相同, 下面我们从原理开始讲解

调试原理

配置调试环境

1) 配置 xdebug

这里使用了最小化配置, 对于 profile 等功能没有配置

1
2
3
4
5
[xdebug]
zend_extension="/usr/local/opt/php70-xdebug/xdebug.so"
xdebug.remote_enable=1 # 启用远程调试
xdebug.remote_connect_back=1 # 忽略 remote_host 配置, 不关注主机配置, 开发者使用最舒服
xdebug.remote_port=9050 # 监听端口

注意 这里监听端口默认是 9000 , 和 php 默认监听重复, 注意尽量不用使用 9000, 以免出现不生效的情况.

2) 设置 phpstorm 配置并开启监听

这里是让 phpstorm 通过监听端口的方式获取到 xdebug 断点传送过来的数据

2.1) 配置端口

我们这里监听的是 9500 端口, 和 xdebug 配置监听数据端口一致

2.2) 开启 phpstorm 数据监听

切换 “开始监听 PHP 调试连接” 按钮。

3) 在 phpstorm 中设置断点

点击行号右侧空白, 设置断点

4) 设置 debug session

debug session 的工具的目的是设置一个 cookie, 让每次发送数据的时候都会携带这个 cookie, 从而识别监听.

4.1) 安装工具

安装 chrome 扩展 Xdebug helper

4.2) 点击 图标设置 session

已经设置了 cookie, Key 是 XDEBUG_SESSION, 值是 PHPSTORM, 我认为这里的值无关紧要, 对于 phpstorm 来说, 是能够监控到的.

5) 运行页面

这里我们在断点位置可以看到输出的内容项目

另一种方式: 内部调用

这里的另外一种方式的服务器配置方式和流程完全一致, 就是第四步和第五步有所不同, 实现的原理是在 phpstorm 中设置运行的服务器, 然后通过 debug 模式自动设置 XDEBUG_SESSION, 并且自动开启监听.

内部调用: 4) 设置 debug session

4.1) 设置 web 访问的服务器

例如我这里的本地域名是 l.dailian.sour-lemon.com, 我们需要配置一个本地服务器来打开这个页面, 我们首先配置一台服务器.

注意 这里的配置的域名是你本地已经配置好开发环境的域名, 端口号是 本地开发所使用的端口, 我这里是 l.dailian.sour-lemon.com 和 80

4.2) 配置调试页面

我们这里创建的调试页面的类型是 PHP Web Application, 服务器选择的是刚才已经建立好的服务器

内部调用: 5) 运行测试页面

这样运行的情况下上面的 2.2) 开启phpstorm 数据监听 步骤可以忽略掉, 这里不需要开启这个监听.

5.1) 开始 debug

点击 debug 按钮, 这里会自动打开一个页面并且传递一个唯一的 ID(可能是进程 ID)作为 debug 值

打开的 url 地址是: http://l.dailian.sour-lemon.com/?XDEBUG_SESSION_START=13608, 这里的数值是会变动的.

5.2) 查看 debug 面板

打开 debug 面板, 会看到相对应的监听 idekey, 这里和上一步设置的 key 是一致的, 同样也和 cookie 中的设置的 XDEBUG_SESSION 值一致

其他帮助

1. 查看兼容性

第一次运行的时候可以通过 phpstorm 自带的工具来检查配置的兼容性.

Run > Web Server Debug Validation

2. debug 帮助面板说明

左侧

绿色三角形 : Resume Program,表示將继续执行,直到下一个中断点停止。

红色方形   : Stop,表示中断当前程序调试。

上方

第一个图形示 : Step Over,跳过当前函数。

第二个图形示 : Step Into,进入当前函数內部的程序(相当于观察程序一步一步执行)。

第三个图形示 : Force Step Into,強制进入当前函数內部的程序。

第四个图形示 : Step Out,跳出当前函数內部的程式。

第五个图形示 : Run to Cursor,定位到当前光标。

框架说明

Frames : 加载的文件列表

Variables : 可以观察到所有全局变量、当前局部变量的数值

Watches : 可以新增变量,观察变量随着程序执行的变化。

参考文章

客户端

Header 约定

说明

软件

开发软件的相关信息

x-os

软件标识, 可选项为 ‘android/ios/h5/webapp/pc/mac/ubuntu/centos’

x-ver

软件版本号, 遵循语义化版本说明 SemVer

x-id

设备 ID, 唯一标示符, 如果是 h5 客户端则应当是自己计算出来的客户端标识, 如果是 android/ios, 则需要实现自己的计算方式

x-app

对于 os, version, id 的 json 字串信息, 以后会废弃(原因是 Nginx 无法解析头数据), 对于其他数据使用 x-app-{ph} 来做替代, 我们现在使用的 header 有

这个在项目中约定, 这里仅仅是举例

1
2
3
x-app-sign : 加密验签版本
x-app-host : 主机头
....

系统

系统 / 设备相关关键信息

x-sys-name

系统平台. 区分大小写, 例如 Android, iOS, iPad, Windows, Mac, CentOS

x-sys-version

系统版本号, 系统的数字标识. iOS 的可能值为 14.6, Android 可能值为 7

x-sys-device

设备型号. iOS 可能值为 iPhone11,6 / iPad,3, Android 可能值为 HuaWei Mate P40

x-sys-cpu

cpu 架构类型. x86, arm64

附加信息

1
2
3
4
x-k1 : 屏幕宽度
x-k2 : 屏幕高度
.....
x-k3 ... x-k10 : 预留(如果没有值, 则应当为空)

默认/重写

User-Agent

用户标识头, 如果是 h5, 则取标准的 agent 浏览器/Webview 信息, 如果是 iOS/Android, 必要的数据组成为

1
2
3
4
5
6
SmobaHelper/5.71.101 (iPhone; iOS 14.6; Scale/3.00), H5 检查是否在 App 内部可以使用 Project 来进行检测
{Project} : 项目名称例如 Huowan/Mixin/Kejinshou
{Version} : 软件的版本号
{Brand} : 设备品牌
{Type} : 设备类型(例如: Mate 20)
{Dp} : 分辨率缩放值

异常

sentry-trace

不做日志搜集

Sentry 允许 H5 进行汇报的标识头, 对接 sentry 之后 web 默认收集信息的头信息, 无需自己设定

Poppy 设置

config/poppy.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
return [
'system' => [
'cross_headers' => [
// sentry
'sentry-trace',
// app
'x-app', 'x-app-host', 'x-app-sign'
// common software
'x-os', 'x-ver', 'x-id',
// system
'x-sys-name', 'x-sys-version', 'x-sys-device', 'x-sys-cpu',
// append
'x-k1', 'x-k2', 'x-k3', 'x-k4', 'x-k5',
'x-k6', 'x-k7', 'x-k8', 'x-k9', 'x-k10',
],
]
]

使用

在 poppy 项目中可以使用 x_header('id') 来获取 ‘x-id’ 参数

Nginx 配置

nginx.conf

1
2
3
4
5
6
7
8
etag on;
log_format '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'"$host" $request_time "$upstream_response_time" '
'"$http_x_os" "$http_x_ver" "$http_x_id" "$http_x_app" '
'"$http_x_sys_name" "$http_x_sys_version" "$http_x_sys_device" "$http_x_sys_cpu" '
'"$http_x_k1" "$http_x_k2" "$http_x_k3" "$http_x_k4" "$http_x_k5" "$http_x_k6" "$http_x_k7" "$http_x_k8" "$http_x_k9" "$http_x_k10" ';

技术经理岗位职责以及任职要求

岗位职责

任务管理:开发工作量评估、定立开发流程, 技术选型、分配和追踪开发任务

质量管理:代码 review、开发风险判断/报告/协调解决

效率提升:代码底层研发和培训、最佳代码实践规范总结与推广、自动化生产工具、自动化部署工具

技术能力提升:招聘面试、试题主拟、新人指导、项目复盘与改进

文档管理: 对文档进行统一管理, 并要求技术人员在开发过程中完善开发文档

技术评定: 对在岗技术人员进行合理的技术评定, 并有有效的晋升机制

组建平台研发部,与架构师共建软件公共平台,方便各条产品业务线研发

通过技术平台、通过高一层的职权,管理和协调公司各个部门与本部门各条线。

推广落实绩效的有关内容
对员工状态进行跟踪, 异常问题进行处理
关注同事的生活状态, 如果有需要公司帮助的, 及时提出
对技术提升有严格, 要求, 需要有技术部分的进步

任职要求

1、技术愿景:识别新技术、利用新技术、整合新技术、驱动新技术。驱动商业战略、驱动产品战略

2、技术架构:建立主营业务中的技术架构与实施模式,建立技术体系标准

3、流程制度:建立高质量,高效率的技术团队。健全的项目管理体系;完善的员工能力发展体系

4、知识培训:建立以研发内容为主的知识库管理体系、技术分享与技术文化的体系

5、业务支撑:与其它部门的沟通协作,如 HR、市场、BD、财务、客服等提供技术管理接口;在产品技术层面能够领先于业内同行

6、影响力:在公司内部与行业中具备一定影响力与口碑

7、视野&格局&执行力:看待问题全面,具有强大的学习力,具备技术前瞻力,敏锐的市场嗅觉,战略落地的能力

Vue 开发规范 1.0 (For Vue3)

本文是 JavaScript 编码规范Web 编码规范 的补充版, 涉及到 vue 独立性的内容在此单独说明

本规范旨在为前端程序的开发者提供规范化最新的指导,可用于程序员个人编译环境以及研发团队集成环境等场合的代码规范化检查。

本文约定于 vue3, 不适用于 vue2

环境约定

  1. Node.js LTS 版本,你可以使用 nvmnvm-windows 在一台电脑中管理多个 Node 版本

  2. 使用 Chrome 浏览器并安装 Vue.js devtools 进行调试

命名

  1. 文件名应该是大写驼峰, 文件名作为组件名称, 组件内不进行组件名称的定义

  2. 单文件组件的文件名应该要么始终是单词大写开头( PascalCase )

  3. 应用特定样式和约定的 基础组件 (也就是展示类的、无逻辑的或无状态的组件) 应该全部以一个特定的前缀开头,比如 Base、App 或 V

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// not good
components/
|- MyButton.vue
|- VueTable.vue
|- Icon.vue

// good
components/
|- BaseButton.vue
|- BaseTable.vue
|- BaseIcon.vue

components/
|- AppButton.vue
|- AppTable.vue
|- AppIcon.vue

components/
|- VButton.vue
|- VTable.vue
|- VIcon.vue
  1. 和父组件 紧密耦合的子组件 应该以父组件名作为前缀命名

如果一个组件只在某个父组件的场景下有意义,这层关系应该体现在其名字上。因为编辑器通常会按字母顺序组织文件,所以这样做可以把相关联的文件排在一起

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// not good
components/
|- TodoList.vue
|- TodoItem.vue
|- TodoButton.vue
components/
|- SearchSidebar.vue
|- NavigationForSearchSidebar.vue

//good
components/
|- TodoList.vue
|- TodoListItem.vue
|- TodoListItemButton.vue
components/
|- SearchSidebar.vue
|- SearchSidebarNavigation.vue
  1. 组件名应该倾向于完整单词而不是缩写
1
2
3
4
5
6
7
8
9
// not good
components/
|- SdSettings.vue
|- UProfOpts.vue

// good
components/
|- StudentDashboardSettings.vue
|- UserProfileOptions.vue

语法

  1. prop 的定义应该尽量详细,至少需要指定其类型

  2. v-for 设置键值;在组件上总是必须用 key 配合 v-for,以便维护内部组件及其子树的状态

    在组件上总是必须用 key 配合 v-for,以便维护内部组件及其子树的状态

  3. 不要把 v-if v-for 同时用在同一个元素上(大部分时候你可以使用计算属性实现)

  4. 模版中的组件名在单文件组件和字符串模板中组件名应该总是 PascalCase 的;

1
2
3
<!-- good -->
<!-- 在单文件组件和字符串模板中 -->
<MyComponent />
  1. JS/JSX 中的组件名应该始终是 PascalCase 的

  2. Prop 名大小写,在声明 prop 的时候,其命名应该始终使用 camelCase,而在模板和 JSX 中应该始终使用 camelCase

1
2
3
4
5
// not good
props: {
'greetingText': String
}
<WelcomeMessage greetingText="hi"/>
  1. 组件模板应该只包含简单的表达式,复杂的表达式则应该重构为计算属性或方法
1
2
3
4
5
6
7
8
9
10
11
// good
// 在模板中
{{ normalizedFullName }}
// 复杂表达式已经移入一个计算属性
computed: {
normalizedFullName: function () {
return this.fullName.split(' ').map(function (word) {
return word[0].toUpperCase() + word.slice(1)
}).join(' ')
}
}
  1. 非空 HTML 特性值应该始终带引号
1
2
3
<!-- good -->
<input type="text" />
<AppSidebar :style="{ width: sidebarWidth + 'px' }"></AppSidebar>
  1. 可简写指令需要缩写 (用 : 表示 v-bind: 和用 @ 表示 v-on:)

组件/实例的选项的顺序

组件/实例的选项应该有统一的顺序,这是我们推荐的组件选项默认顺序:

  1. 副作用 (触发组件外的影响)
    • el
  2. 全局感知 (要求组件以外的知识)
    • name
    • parent
  3. 组件类型 (更改组件的类型)
    • functional
  4. 模板修改器 (改变模板的编译方式)
    • delimiters
    • comments
  5. 模板依赖 (模板内使用的资源)
    • components
    • directives
    • filters
  6. 组合 (向选项里合并属性)
    • extends
    • mixins
  7. 接口 (组件的接口)
    • inheritAttrs
    • model
    • props/propsData
  8. 本地状态 (本地的响应式属性)
    • data
    • computed
  9. 事件 (通过响应式事件触发的回调)
    • watch
    • 生命周期钩子 (按照它们被调用的顺序)
      • beforeCreate
      • created
      • beforeMount
      • mounted
      • beforeUpdate
      • updated
      • activated
      • deactivated
      • beforeDestroy
      • destroyed
  10. 非响应式的属性 (不依赖响应系统的实例属性)
    • methods
  11. 渲染 (组件输出的声明式描述)
    • template/render
    • renderError

元素特性的顺序

元素 (包括组件) 的特性应该有统一的顺序,这是我们为元素特性推荐的默认顺序:

  1. 定义 (提供组件的选项)
    • is
  2. 列表渲染 (创建多个变化的相同元素)
    • v-for
  3. 条件渲染 (元素是否渲染/显示)
    • v-if
    • v-else-if
    • v-else
    • v-show
    • v-cloak
  4. 渲染方式 (改变元素的渲染方式)
    • v-pre
    • v-once
  5. 全局感知 (需要超越组件的知识)
    • id
  6. 唯一的特性 (需要唯一值的特性)
    • ref
    • key
    • slot
  7. 双向绑定 (把绑定和事件结合起来)
    • v-model
  8. 其它特性 (所有普通的绑定或未绑定的特性)
  9. 事件 (组件事件监听器)
    • v-on
  10. 内容 (覆写元素的内容)
    • v-html
    • v-text

单文件组件的顶级元素的顺序

单文件组件应该总是按照 <template><script><style> 的标签顺序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- good -->
<!-- ComponentA.vue -->
<template>...</template>
<style>
/* ... */
</style>

<!-- ComponentB.vue -->
<template>...</template>
<script>
/* ... */
</script>
<style>
/* ... */
</style>

隐性的父子组件通信

应该优先通过 prop 和事件进行父子组件之间的通信

一个理想的 Vue 应用是 prop 向下传递,事件向上传递的。遵循这一约定会让你的组件更易于理解。然而,在一些边界情况下 prop 的变更或 this.$parent 能够简化两个深度耦合的组件。

问题在于,这种做法在很多简单的场景下可能会更方便。但请当心,不要为了一时方便 (少写代码) 而牺牲数据流向的简洁性 (易于理解)。

非 Flux 的全局状态管理

应该优先通过 Vuex 管理全局状态

Vuex 提供的不仅是一个管理状态的中心区域,还是组织、追踪和调试状态变更的好工具。

项目开发流程 v3

本工作流的主要目的是规范需求, 跟踪项目进度和任务进度, 让项目按照既定的时间有序开发.

1. 需求评审

参与人

产品部/运营部相关人员

目的

根据公司经营策略和对行业的洞悉, 制定出来相关的开发基调, 确定版本需要开发的功能, 确定版本号, 大概功能周期, 形成有效的产品计划.

过程 :

  • 收集需求
    通过各种渠道汇总需求, 进行统一的记录整理
  • 需求评审(产品经理)
    明确需求, 确认需求的可行性, 并确定基本的业务逻辑
  • 产品规划
    制定产品文档, 规划版本, 确定大致开发周期, 需要描述清楚详细的功能点

2. 产品设计

这里包含两个部分, 原型/交互开发, UI 界面开发

2.1 原型设计以及评审

参与人

产品经理 / 产品助理

目的

根据描述的功能点确定产品的原型文档, 满足在需求评审中所有的需求点, 并且使用交互语言的形式将功能告知给 UI/CTO, APP LD, 让开发熟悉整个流程并开始技术储备, 让 UI 设计师懂得功能点, 并且进行界面的开发工作

产出内容

  • 原型图
    能够让设计根据原型图内容进行设计
  • 业务流程图
    让开发明白/清楚整个开发流程, 根据产品的业务逻辑来描述用户的操作, 每一个不可拆分的步骤便是不同的用例
  • 页面流程图/可以和交互稿互为补充
    让开发知晓页面的设计流程以及跳转方式[如果有特殊的说明需要标注, 否则遵循先入先出原则]
  • 兼容性说明
    需要考虑清楚对已经上线版本的兼容程度以及如何对线上的数据进行容错处理
  • 新增功能
    新增功能需要开会来进行跟踪, 并且及时告知开发与测试
  • UI 开发清单

2.2 UI 设计以及评审

负责人

产品经理 / UI 设计师

目的

形成和原型一致的设计图, 并用交互的方式把功能描述清楚

产出内容

与原型图一致的设计图
根据 UI 清单来进行设计

2.3 交互稿/高保真

负责人

产品经理 / UI 设计师

目的

形成交互稿, 动效的对界面之间的步骤进行说明

产出内容

  • 交互稿
    基于设计图的交互稿, 高保真的设计稿
  • 出具状态说明
  • 出具效果说明

3. 筹建

3.1 需求说明

负责人

产品部, 测试部

准备

  • 任务模块清单
    这里把任务根据模块进行区分, 并详细罗列出任务点(详细到页面/操作即可).如果有需要追加的功能, 任务清单在项目中起到跟踪的作用
  • 原型图 / 设计图 / 交互图
    使用设计交互图和大家进行说明, 对产品功能进行详细的阐述
  • 模块开发优先级
  • 开发者/测试准备
    准备详细聆听, 并对产品有疑问的地方进行提问, 目的是弄透彻需要开发的产品内容. 开发者对不明白的地方和产品进行讨论, 确定产品开发的详细功能点.
  • 测试
    准备最近版本记录的 bug 问题, 需要在本版本中安排完成的, 需要在会议中确认

注意(3.0)

如果是版本在开发中需要新增的需求也需要按照正常流程去给开发/测试进行说明, 在核对的时候需要确定, 新增的功能在任务清单中以不同的颜色标注, 便于开发核对, 注意

  • 解释要加的功能的作用
  • 上线时间是否存在变动, 如果不变动, 开发是否可以承接
  • 进行整个团队的会议通知, 不允许单独, 口头通知开发

3.2 拆解

负责人

开发小组组长/ 技术经理

流程

团队内部人员(App/Test/Dev) 进行内部协商, 对开发的详细细节进行沟通

结果

  • App 前端组
    详细拆解功能点内容, 并对功能流程, 接口有详细的了解, 根据任务情况和前端组负责人进行沟通协调, 确认统一的开发先后顺序, 以及开发工时
    确定不同端统一的开发流程, 逻辑
  • 后端组
    后端根据功能点, 分配开发者, 由开发者对功能点进行业务逻辑拆分以及功能点拆分, 将功能点文档以及时间计划落实到 [Wps文档], 将业务逻辑及开发流程图落实到语雀上. 这里需要和前端确认出来接口参数. 技术实现流程图.
  • 测试组
    确认模块以及用例内容(根据步骤去进行操作), 并对模块的用例拆分/细粒度以及负责人,完成时间进行确定, 并将时间计划统一记录在 Wps 文档中.
  • 部门之间的配合
    测试和开发进行详细配合, 需要知道步骤,以及步骤之后的数据流转情况, 这样准确对问题进行核对以及不会漏掉东西

产出内容

  • 技术流程(项目负责人负责)
    在业务逻辑的基础上完善技术流程, 需要描述清楚技术操作步骤背后的影响, 便于测试对操作结果进行跟踪, 测试根据技术流程完善用例
    技术经理对技术流程负责, 对流程的技术步骤负责, 测试根据业务流程拆分用例, 根据技术流程拆分用例
  • 用例大纲(测试组长)
    列出来用例大纲, 根据用例大纲完善用例, 大纲需要明确(模块/子模块/操作), 用例拆分的标准是最小功能点(不可拆分)
  • 用例详细(测试组长)
    根据大纲来进行用例的编写

4. 规划

4.1 计划

负责人

项目经理

准备

任务计划(App/Dev/Test)

目的

  • 审核任务功能点, 确保任务无遗漏
  • 审核任务时间/负责人, 确认每个人对自己的功能点实现以及时间都知晓, 需要细化到工时, 如果没有工时, 则需要进行讨论, 并按照工时的情况确认下来.
  • 确定开发完成时间点
  • 确定预期上线时间点

产出内容

  • 工时预估清单
    功能清单需要细致到工时, 并且明确打包交付测试的时间
  • 项目任务列到云效上
    项目根据工时预估的清单列举到云效上, 使用项目里程碑并且对项目内容进行跟踪

4.2 用例评审

负责人

产品/测试

产出内容

  • 对用例进行评审, 需要明确页面跳转, 用户操作, 以及操作之后的结果
  • 保证产品文档理解的准确无误
  • 大纲(流程文档/设计文档)

用例主要的目的是保留最新的测试用例, 如果有里程碑, 则在第一个里程碑之前进行核对, 如果没有, 则在完整测试前完成用例核对即可, 确定上线时间, 周期

5. 开发

5.1 开发

负责人

开发者

产出内容

开发者需要根据总计划对开发内容进行划分. 根据里程碑/工时 需要确定出来周的开发内容, 并于日报中对今日开发内容以及明日的开发计划进行说明, 需要注明 task # xxx, 并且需要出具线上的配置文档

由项目经理进行跟踪, 对开发情况进行每日跟踪, 如有延期,由提出申请, 阐明延期理由以及延期时长, 根据原因来评定是否对其延期纳入绩效考核.

通知跟踪
钉通知说明参考规范:
https://kdocs.cn/l/smt1vWKJh?f=101 > [文档] 钉钉通知规范.xls

5.2 提测

负责人

项目经理

产出内容

产品交付测试

  • 后端
    后端配置好环境, 对代码进行部署, 并且保证代码无缓存, 可以正常执行
  • 后端优化内容
    不在本期任务只内的任务清单
  • 前端
    开发包(这里打包时间以上传并告知测试为准)

5.3 测试

负责人

项目相关联负责人

轮次 1 : UI 进行验收[动效/状态/机型], 测试进行验收
轮次 2 : UI 复验, 测试复验
轮次 3 : 保障性测试, 压力, 注入, 性能 - 出具测试报告

  • 用例测试
  • 界面跳转测试
  • 页面流畅度测试,
  • bug 级别进行定义
  • 兼容性测试

测试过程中不要对已经部署的代码进行调整(可以切换分支去修改 bug 不要在测试运行的环境中去更新代码)

里程碑说明 : 测试仅仅测试里程碑功能点, 例如 A. B. C. 三个里程碑 , C 测试需要验证 B, C 的功能点.

6. 上线

6.1 部署

参与人 : CTO/测试/后端 LD/产品/运营

  1. 已测软件符合上线标准,相应负责人签字;
  2. 需要明确线上的处罚决定

Test

核对运营需要准备的资料(配置资料), 上线前的沟通

运营

需要准备的线上数据/图片是否完整

后端 LD

核对上线的流程, 测试的流程以及相应的步骤

6.2 总结

负责人

测试组长

产出内容

测试报告
测试报告需要包含

  • 开发者每次打包的时间
  • 用例总数(老功能数量/新功能数量)
  • UI 的开始以及结束时间
  • 测试的开始以及结束时间
  • 开发的预计修改 bug 的开始时间以及结束时间(需要区分平台)
  • bug 的分布/级别以及责任人

总结需要对出现的问题做一下总结, 并且对数据做统计, 并对责任人进行奖惩.
奖惩的话需要有细节做说明, 还必须要有相应的计算方式, 这个需要考核, 主观因素占比降低
测试在钉钉预约时间(时间尽量控制在下班前半小时左右, 不要耽误太多的正常开发时间)

惩罚:确定 bug 严重程度,确定相关责任人的惩罚金额,由人事配和完成;
整理到纸质上线出问题处罚表里,也需要整理到文档里;

项目奖惩制度需要落实绩效制度 [todo] 绩效考评制度
对项目需要的部分进行绩效考核.

6.3 线上质量跟踪

线上出现的所有问题全部提交给测试,由测试进行复现/bug 级别定义

bug 版本发布

线上出现的问题经过复测后必现后由产品进行版本规划, 修改完成之后需要记录工时, 便于绩效跟踪[todo] 这里需要有上线跟踪文档以及是否计入工时

Test

测试对整体项目进行总结, 对项目测试/对接中的问题进行汇总汇报

延期人员

由延期人员对延期时间做一个说明

版本负责制(项目跟踪)

开发者/测试/App 开发 对本次项目开发过程中线上出现的问题负责, 测试/前端/后端存在连带责任.

责任界定

  • 对当前版本负责

附录: 开发跟踪

1. 项目立项过程跟踪

这里需要有文档

  • 确定项目版本/主要功能点
  • 确定开发周期以及相应负责人
  • 确定里程碑功能和时间点
  • 确定完整测试时间点
  • 确定上线
  • 对 bug 进行跟踪维护

2. 项目开发跟踪

每晚对工作内容完成度进行核对, 进行任务跟踪, 如果有需要 LD 组织问题进行商讨, 提出相应的解决方案, 如果有差异, 需要当日提出, 并提出相应解决方案

3. 绩效跟踪

  • 流程不顺畅导致进度跟进异常的(2+)
  • 任务未进行计划的(2+)
  • 任务指定/计划且未进行跟进的(2+)
  • 任务不承接(5+)

4. 用例拆分的示例

用例模板 测试工作中各类测试用例的简要模板

注意事项

  • 确定用例拆分时间
  • 确定技术流程的后台影响
  • 用例评审
1
2
用例大纲
用例

附录: 更新

v3.1(2021 年 10 月 25 日)

  • 去除文档不必要的内容
  • 更新到 wulicode 中

v3.0(2020 年 11 月 03 日)

  • 简化流程

v2.3(2019 年 06 月 04 日)

  • 加入跟踪内容

v2.2(2019 年 03 月 24 日)

  • 增加绩效考核
  • 增加负责人制度

v2.1(2019 年 02 月 26 日)

  • 完善流程, 增加 UI 核对
  • 增加单独配置信息

v2.0(2019 年 02 月 11 日)

  • 使用最新版的开发流程进行书写
  • 增加细致跟踪

v1(2018 年 11 月 8 日)

  • 初级第一版本
  • 描述整个开发流程

测试工程师 - 岗位评级

岗位职责

  • 功能测试任务

    • 和产品核对需求并编写测试用例, 如有需求变动及时修改用例
    • 制定测试计划
    • 对开发出的产品进行完整测试
    • 对开发修复的问题进行回归测试
    • 对测试结果进行记录, 总结
  • 文档任务

    • 编写技术帮助中心, 线上出现相关问题说明文档(开发过程中的文档)
    • 对线上的数据进行记录并生成报表
  • 性能, 压力

    • 对开发软件进行性能测试
    • 接口的完整覆盖测试(线上无损)
    • 跟踪线上性能指标, 将指标以及不稳定行反馈给开发并进行下一步工作推进
    • 性能指标包含 接口性能, 压力测试, app 性能, 崩溃率, 慢接口
  • 上线

    • 上线前改动部分内容与运营, 产品进行确认, 引导运营进行后台的配置
    • 对 bug 进行跟踪, 对业务及运营等提出问题及遗留问题进行跟踪测试;
  • 根据产品经理提供的文档对功能进行复核

  • 编写使用说明书

    • 各模块介绍以及使用说明
    • 模块的相关性(前台/后台)

岗位评级

软件测试实习生(学习阶段)

1、软件相关专业毕业,但对工作性质、内容有一定了解,暂时不具备胜任工作的基本技能;

2、掌握软件测试的理论知识,熟悉软件测试相关工具,

3、有成为软件测试工程师的意愿和潜力,值得公司培养;

软件测试助理(参与工作)

1、能看懂产品原型、UI 设计,熟悉软件测试工具,对基础知识掌握比较完善;

2、能在指导下根据产品原型、UI  设计发现并提交 bug;

3、熟悉工作的流程,能明确直属上级在工作输出上对自己的要求;

软件测试专员(指导下完成工作)

1、能根据产品原型、UI 设计发现并提交 bug;对提交的 bug 进行跟踪和管理,能进行回归性测试;

2、对测试工作的要求、流程有充分认识,能根据流程进行基本的测试,

3、遇到困难能积极寻求帮助、主动查找解决方案,推动项目进展;

4、能明确自己的工作职责,顺利开展工作;

5、能够融入所在部门,能够和同事相互协作;

初级软件测试工程师(独立完成工作)

  1. 能根据产品原型、UI 设计准确的发现并提交 bug,独立完成里程碑测试;
  2. 能针对发现的 BUG 及时有效的和相关负责人进行沟通,督促其完成修改进行回归性测试;
  3. 能独立解决工作中遇到的问题,有自己的主观逻辑思想,能对 BUG 作出明确判断;
  4. 能严格按照规范流程进行测试工作,并能严格要求自己;
  5. 能够主动和同事进行有效沟通,解决当前问题,推动项目进展;
  6. 能够在他人带领下独立完成测试工作
  7. 有测试的想法和思路,能够编写测试用例,能够理解需求,能够自律

实施软件测试,并对软件问题进行跟踪,推动测试中发现问题及时合理解决

能独立解决工作中遇到的问题,有自己的主观逻辑思想,能对 BUG 作出明确判断,并且按流程、规范完成所承担测试工作

选择、确定并验证所承担任务的具体测试方案,能够主动和同事进行有效沟通,解决当前问题,推动项目进展

参与项目计划制定

完成所承担工作的文档

完成直接领导分配的其他工作,及时根据工作安排进行合理的优先级改变

中级软件测试工程师(指导工作)

1、熟练掌握测试工具和测试方法,能独立完成项目的整体测试,并给出评估报告;

2、针对项目有自己的见解,能够参与项目的整体方案讨论,给出合理建议;

3、能整理出逻辑思维漏洞、常见 bug 类别,给予其他同事技术指导、帮助其完成测试工作;

4、了解行业新的测试技术和测试工具,结合公司的实际情况将其应用到实际工作中,改善测试环境、提高测试效率;

5、能根据测试进展,合理分配时间,安排好测试项目的具体进程;

有较多相关软件测试经验,可以承担多个项目的完整测试工作

可以很快的分析和理解测试用例并可以找到问题,实施软件测试并对软件问题进行跟踪、复现,推动测试中发现问题及时合理解决

针对项目有自己的见解,能够参与项目的整体方案讨论,给出合理建议

了解行业新的测试技术和测试工具,结合公司的实际情况将其应用到实际工作中,改善测试环境、提高测试效率;

5、能根据测试进展,合理分配时间,安排好测试项目的具体进程;

高级软件测试工程师(主导工作)

1、参与过中型以上项目测试,对系统的测试方案有所了解;

2、能熟练、高效、准确的完成测试工作,并给出可行性意见报告;

3、能够根据各个测试项目的进展,制定出整个部的详细工作方案,主导工作进展;

3、能够对测试中出现的各种逻辑思维漏洞、常见 bug 进行分类汇总并找出解决方案,能对其他同事进行技术培训;

5、能够制定测试的规范流程,并监督实施;

有较深的相关软件测试的经验,承担多个项目的完整测试工作

对先关行业有较多经验,对程序设计有一定经验,具有技术创新能力,为软件测提供新的方法和新的技术

能够根据各个测试项目的进展,制定出整个部的详细工作方案,主导工作进展;

能够对测试中出现的各种逻辑思维漏洞、常见 bug 进行分类汇总并找出解决方案,能对其他同事进行技术培训;

能够制定测试的规范流程,并监督实施;

有较丰富的软件测试专业技能和工具运用技能,特别是从专业实践中获得的技能

资深软件测试工程师(全局把控)

  1. 拥有多年的项目测试经验,熟悉各种技术和应用场景,带领过中型以上项目测试;
  2. 熟悉整个测试环境的搭建,能够提供系统测试方案;
  3. 能够预估项目风险、告知技术疑难,提出规避方案,全局把控测试工作;
  4. 有能力管理整个测试审核部门、建立完善测试规范和流程;
  5. 能根据客户需求、受众情况对产品原型、UI 设计、技术研发进行深入分析提出可行性建议;

软件测试工程专家(前瞻规划、实施)

1、拥有丰富的研发、测试经历,能带领团队进行大型项目测试;

2、能建立、建全质量监控管理体系和内部管控系统;

3、能根据公司的发展需求,追踪收集测试新技术,能通过系统培训,提高团队能力;

4、对行业行情有深入研究,能根据公司现状、发展需求对测试部门进行前瞻性的职能规划,满足公司发展需求;

UI 设计师

工作内容

一、UI 设计师(APP)

  • 根据产品经理提供的产品需求,对产品的整体美术风格、交互设计、界面结构等做出设计;

  • 负责项目中各种交互界面、图标、LOGO、按钮等相关元素的设计与制作;

  • 能积极与开发沟通,推进界面及交互设计的最终实现。

  • 对页面进行优化,使用户操作更趋于人性化。

  • 进行界面完成后的尺寸标注工作

    • 制定相应的颜色以及尺寸规范
    • 进行界面的切图与图标提供工作
  • 辅助开发进行项目进展工作

  • 维护现有的应用产品

二、UI 设计师(网站)

  • 负责网站项目的整体版式、风格设计。
  • 进行对外合作的广告及专题设计。
  • 与前端配合进行界面切图以及图标提供工作
  • 进行尺寸的标注工作
  • 辅助开发进行项目进展工作
  • 以用户为中心的设计理念,对页面进行优化,改善网站用户体验。

三、广告设计

  • 设计相关的广告图片,PC 端与 APP 端

四、其他部分

UI 标准的指定

用户体验设计

交互设计

评级

初级

视觉设计的基础级别

视觉能力:

  1. 能用 PS 等绘图工具进行矢量或像素类的图形绘制
  2. 掌握 PS 中的图层样式、滤镜、图层叠加等功能,能模仿别人作品中所体现的造型和质感。比如知道了怎么用矢量或非矢量方式去勾画和调整图形,而不会造成边缘模糊等问题的;怎么用高光+渐变去体现形体质感的;知道哪里能弄到一些材质去贴上去得到什么样的效果等等。
  3. 懂得输出切图、懂得程序实现的方式和术语之类的。

交互能力:

  1. 知道交互是啥,明白软件流程图。
  2. 能在没有交互图的情况下看一个参考图或是领导的几句话就去做设计,也就是知道上哪去抄一些界面的交互过来的。

这就是初级的 UI 设计师,我相信大部分设计师都是停留在这个阶段,毕竟这样要达到,都有一定的难度的。需要很多临摹,很多实践,才能积累下来的。

中级

视觉设计需要突破到一个新领域的级别

视觉能力:

  1. 满足初级能力
  2. 能达到像素级的刻画,比如 16x16 的图标修整等,眼睛也要有像素级别的眼睛,一看就知道那里不对劲和是不是没有对齐等等。为何不把小图标的修正放到 C,是觉得这个确实不是每个公司都需要那样去做的。
  3. 懂得质感与色彩的搭配,了解整个行业的设计动向,比如风格、质感等,并且掌握其实现的技巧和懂得利用这些知识去创新设计。
  4. 有一定的设计理论,并能利用这些理论去输出进行教学,或是用于说服你的领导或客户。

交互能力: 5. 对于交互有比较深入的理解,并且已经能够胜任交互设计的工作。 6. 有一定的沟通能力,能清晰的表述整个设计的逻辑和交互方式。 7. 能根据产品文档或领导口述进行交互图制作,并且参与 PK 会议,能不能胜出我觉得还是靠别人是不是认可你的,不是靠自己说了就能赢的,哈哈。

用研能力: 8. 掌握用研基础,实时关注用户的反馈,认真去分析用户反馈的真实问题在哪,而不是盲目听从和跟风。 9. 掌握用研的方式和分析其有效性

高级

一个把控和平衡全局级别

综合能力:

  1. 满足中级能力,这里会发现已经不分交互和视觉或用研来说了,因为本身这几个领域在我看来它就是一体化的东西,不能拆分的。拆分就是等于缺胳膊少腿的,等别人的决定干事情,自己天天就等拍板那种。
  2. 能把交互和视觉两者都完美的做一个结合,做到可牺牲交互,或可牺牲视觉效果,拿捏自由。其实这里甚至会涉及到产品功能一些删减和修改其原有的功能方式都说不准。
  3. 有一定的程序开发逻辑知识,这里指的逻辑不是程序源代码,而是开发的一些实现方式,比如我在做 QQ 输入法的时候,设计皮肤底层就是和程序去 PK 皮肤底层的实现,并不需要懂代码,但是要把原理都解释清晰和皮肤实现架构都构造好。
  4. 设计初期能对交互框架,视觉框架,程序实现框架都很清晰的去了解,做到一次大的设计支持,而后面的版本变更不用有太大的改动,比如资源加载简便和多次复用。当然这里会存在很多因开发时间不允许的情况,那就看怎么去衡量这个问题了。

作为视觉来说,如果实现皮肤的底层强大,足以支持未来几年的需求,那么之后的工作会顺利很多的。这里又要拿 QQ 输入法举例,当时的底层设计的时候支持蒙板遮罩、Apng 动态图、切图带链接等。所以到今天为之,这个底层可以适应各种皮肤,如相框皮肤、动态皮肤、点击皮肤进入网站等等。而听说搜狗输入法现在的皮肤底层有 3 套架构在支持不同类型的皮肤,这就是当初设计的时候考虑欠缺或是开发时间限定的原因。这会导致安装包臃肿和系统缓慢,或是皮肤实现困难工作量大等问题。 5. 从用户研究中分析出准确的原因,并且提出实效的建议去解决问题。 6. 熟悉各种终端的交互和视觉规范或风格特性等。比如 pc、mac、ios、安卓之类的,并且在上面利用其特性合理的进行设计。

神级

所谓的 S,就是未能划分的,全都丢到 S 去,一般这样的情况的时候,人的能力点都非常突出和饱满了,就会往自己的方向去走了。那就是在这个阶段会孵化出独特的个人能力和魅力,会产生出不同形态的神级设计师。

综合能力:

  1. 高级产品经理能力。把产品经理的能力放到神级里面来说,因为能不被产品牵着头来走的视觉本身就少之又少,所以能自我控制产品方向的时候,那就完美了。

那么,如果单纯设计一个外形的话,看似是一个视觉的事情,但是要由产品去定义其个性和功能点,交互定义其行为方式,视觉最终去实现的话,通常都会出现很有趣的状态,我把他称为肢解再组合的产物。 2. 自我体现能力,通常这个时候,应该是积累很多的了,会根据经验和能力产生出独特的念能力的。

也就是说,会形成一个独特的神级形态,比如有些是喜欢在级别 B 的基础上,做专攻视觉的大师,把视觉发挥到极致,不管多么不合理的交互,都可以用视觉去弥补。或则是在 A 的基础上,做产品经理,来让引导整个局面等等,这里其实可以不用说特别多的例子,因为在这里去分化的话,是不可控的,结果也是很精彩的。 3. 神级设计师的地位,因为在这个行业里面的时间很长才能达到,所以资格会很老,加上嘴巴也很能说,自然会各有千秋。

[原] 在 PhpStorm 中使用 Xdebug 生成 php 的 Profiler

说明

以下内容摘抄自 profiling PHP 脚本

xdebug 的 profiler 是一个强大的工具,它能分析 PHP 代码,探测瓶颈,或者通常意义上来说查看哪部分代码运行缓慢以及可以使用速度提升。Xdebug 2 分析器输出一种兼容 cachegrind 文件格式的分析信息。这允许你能使用出色的 KCacheGrind 工具(Linux,KDE)来分析你的 profiling 数据。在 Linux 可以使用你最喜欢的包管理器安装 KCacheGrind。

在 windows 系统上,有预编译的 QCacheGrind 二进制程序(QCacheGrind 是没有 KDE 绑定的 KCacheGrind)。

在 Mac OSX 系统上,这里也有怎样安装 QCacheGrind 的说明

Windows 用户可以选择性的使用 WinCacheGrind。它的功能不同于 KCacheGrind,所以 这个页面的 KCacheGrind 使用文档章节不适用于这个程序。WinCacheGrind 目前不支持 Xdebug 2.3 引入的 cachegrind 文件格式的的文件和函数压缩。

这也有一种可替代 profile 信息演示的工具叫做 xdebugtoolkit。一款基于 web 前端叫做 Webgrind,和一款基于 java 的工具叫做 XCallGraph

如果你不能使用 KDE(或者不想使用 KDE)的 kcachegrind 包,可以用 perl 脚本 “ct_annotate”,它能从分析器跟踪文件生成 ASCII 输出。

配置

1) Xdebug 配置

这里依旧使用最小化配置

1
2
3
4
5
; profiler
xdebug.profiler_enable = 0; ; 关闭永久生成profiler
xdebug.profiler_enable_trigger = 1; ; 启用 session 触发 profiler
xdebug.profiler_output_dir = "/data/profiler_dir" ; 输出的目录
zend_extension = "/usr/local/opt/php70-xdebug/xdebug.so"

配置完成之后重启 php-fpm 或者 apache

2) 安装 xdebug 工具

安装 chrome 扩展 Xdebug helper

3) 启用 Xdebug helper 的 profiler 工具

4) 刷新页面, 查看设定的文件夹

在上边设定的文件夹中会生成 profiler 文件

Xdebug 生成的结果是 CacheGrind 格式

5) 使用工具来分析 profiler 文件

这里我使用 phpstorm 的分析工具来查看

Tools > Analyze Xdebug Profiler Snapshot

选择生成的 输出文件, 可以看到文件的解析信息, 这个对于分析自己写的php代码会有很大益处

参考文档

标准化说明

所谓标准化就是必须要要执行的内容是开发的下限, 是本职工作中必须要做的事情, 并且是不能够去违背的, 也就是规则

一些是开发的规则
一些是职业的规则

对于代码部分的规则, 参考代码规范, 这里是对业务部分和职业部分进行标准化约定

iOS 开发工程师

工作内容

  • 对项目负责,负责软件项目的详细设计、编码和内部测试的组织实施,完成分配项目的实施和技术支持工作。

  • 与项目相关人员配合共同完成应用软件的开发工作;

    • IOS 平台开发环境(平台及工具软件)的设计、实现和维护
    • 按照项工作目计划在保证质量的前提下、按时完成开发任务
    • 负责与服务器端调试,确保应用质量
    • 适应性维护
    • 提供技术指导,促进系统操作技术和译码编程的有效使用
  • 参与需求调研、项目可行性分析、技术可行性分析和需求分析。

  • 熟悉并熟练掌握交付软件部开发的软件项目的相关软件技术。

  • 负责向项目负责人及时反馈软件开发中的情况,并根据实际情况提出改进建议。

  • 参与软件开发和维护过程中重大技术问题的解决。

  • 追踪上线情况已经线上存在问题。

  • 跟踪 IT 技术进展,做好技术储备

初级工程师:

  • 精通 OC/Swift 语言基础 精通 UIKIT 熟悉网络通信机制 具备主流开源框架使用经验,研究过源码,并懂得他们的原理,

  • 完成基本的页面搭建,通过三方库的引用于使用完成功能

  • 熟悉常用网络框架并使用网络框架进行上传

  • 熟悉 iOS 常用内置的 API

    • 消息传递:代理、block、通知;
    • 数据存储:sqlite、xml、json;
  • 能根据业务逻辑,完成数据与 UI 的对接

    • 第三方:分享、登录、支付等;
  • 了解视图加载顺序

中级工程师

  • 能够快速完成界面搭建以及较为复杂页面搭建
  • 能够根据项目业务逻辑以及项目需求封装出常用的工具类
  • 熟练常用 iOS 内置 API
  • 能根据业务需要快速选择合适的第三方,并快速完成第三方学习.
  • 了解常用第三方框架底层并能做二次封装
  • 具备基本的架构能力.能够根据项目以及业务方向设计健壮的项目架构 较好的编程习惯
  • 具备一定的产品意识

扎实的编程基础、数据结构、算法基础 深入理解语言机制、内存管理、网络、多线程、GUI、运行时 精通常用设计模式、框架、架构 良好的分析、解决问的能力 熟悉 Core 相关的框架 单元测试

能够接受各种新功能的开发(这里是指,即使你没有做过,但是你仍然可以凭借着学习,解决任何业务需求:例如:蓝牙.AR.摄像头.硬件交互.等)

  1. 音频、视频的使用;
  2. 简单动画效果;
  3. 运行时 runtime、RunLoop;
  4. 线程的使用(GCD&NSOperation);

中级知识点

设计模式

• UIScrollView/UITableView/UICollectionView 的嵌套

• 动态行高

• 通知/代理/block

• 程序启动原理 • 触摸事件/手势

• 图文混编

• Runtime

• NSRunLoop

• GCD

• ReactiveCocoa 开发

• 3DTouch

• 界面渲染

• Charles 花瓶抓包

高级工程师

第三方库安全性评估

架构风险评估,项目风险评估

具备创新并开发出新框架的能力

有自身技术专项领域.在这个领域有积累有造诣,解决公司核心业务.比如项目安全.图形图像处理,音视频.能够帮助公司攻克技术难度,做技术预研.

解决研发过程中的关键问题和技术难题(方案和思路)

调优设备流量、性能、电量

较强的软件设计能力,动态加载,异步绘制框架

对 iOS 内部原理有深刻理解

高级算法:加密等

逆向,OpenGL ES, Metal

iOS 高级知识点

XMPP 加密

Socket

MD5 详解 Base64 加密解密 RSA 非对称加密 AES 对称加密

音频

基础 Core Audio Audio Toolbox OpenAL AVFoundation Speex 语音聊天 AudioQueue/AudioSession Speex 简介

视频

AAC 视频.H264 推流 P2P 传输

直播

直播的技术分析与实现 RTMP 协议 RTMP 直播应用与延时分析 如果做一款 inke 版的 App 推流发布和播放 RTMP FFmpeg 基于 FFmpeg 的推流器 HLS 流媒体传输协议(HTTP Live Streaming) FFmpeg ijkPlayer

算法

简介 冒泡排序 快速排序 插入排序 归并排序 二分查找 希尔排序 动态规划 堆排序

资深工程师:

精通底层原理,数据结构等,可以进行二进制重排

能领导公司相关方面的研究、开创业界一些实践

对公司某一方面的战略规划和未来走向产生影响

精通高性能编程以及性能调优(前期性能瓶颈分析)

灵活运用数据结构、算法解决复杂程序设计问题

提供性能优化、日志搜集、统计分析方案

架构、模块设计

App 内核

底层框架的解读;

  1. 工程架构;
  2. 高级动画效果实现;
  3. 网络编程、socket 编程;
  4. 视频、直播底层技术;
  5. 即时通讯底层技术;
  6. 人脸识别;
  7. 性能检测;

自身:跨平台技术学习、iOS 开发语言学习(Objective-C、swift)、SQL 使用

运维 - 岗位职责

例行工作

  • 访问请求高于 300 ms 的链接定时发送,过滤唯一性链接(每周两次发送)
  • 404 日志错误链接定时发送(每日一次)

工作职责

一、 开发环境

  • 1、规整开发环境,设定自动开发环境部署,构架自动开发平台 devauto 建设。
  • 2、管理 git/svn 代码版本控制并实现本地、测试与线上代码的管控和流程优化
  • 3、按照开发要求,提前搭建、添置开发新组件、环境和系统;
  • 4、构建内部开发 WIKI 知识体系,为技术员工入职技术培训提供支撑,尽快熟悉代码开发流程与规范;

二、线上服务器管控

  • 1、根据产品要求,构建可靠的网站、应用服务平台并保证正常运行;
  • 2、保障线上网站 ixdcw 平台正常运行。使用 Zabbix NAGIOS 等监控软件,对服务进行监控,异常处理,自动恢复,系统瓶颈分析和报表周期汇报;
  • 3、监控数据库的正常运行。获取慢查询信息,并自动去重复,发送给指定的开发人员对数据进行优化和代码调整;每天进行一次汇报;
  • 4、网站数据访问分析;分类整理网站访问日志、APP 的访问日志并做汇总和分析,并自动发送给指定人员。每天一次。每月 1 次大汇总;
  • 5、部署自动化运维工具 ansible 或 SaltStack 提高对服务器平滑部署和管理的可行性和效率;

三、系统安全

  • 1、设定信息发布堡垒机,ssh 安全连接堡垒机,合理分配使用账户,并使用周期检查和修改密码方式,保证信息发布入口安全;
  • 2、设定测试环境访问限定、mysql 连接安全、优化系统运行账户安全、运行权限和登陆日志安全检查,并定期汇总;
  • 3、部署硬件防火墙(软件防火墙),和入侵检测系统并设定合适测试,防止 CC 工具和 DDOS 等网络攻击;
  • 4、应用服务器(php nginx lvs mysql)设定合理的防火墙策略,对异常请求和访问进行自动过滤和攻击防范,强加安全;
  • 5、关注漏洞网站,针对系统漏洞和应用漏洞进行组件升级、应用升级和系统升级。
  • 6、定期对网站进行风险评估、压力测试和应用访问统计来升级硬件、拓展服务。
  • 7、定期更换关键系统的密码。

四、数据安全

  • 1、每日对开发人员提交的代码库定时备份;
  • 2、定时备份开发人员使用的数据库和数据库结构;
  • 3、每天对线上运营服务器数据库进行完整备份、完整单表备份、完整数据结构备份。并使用主从库来保证数据的实时性;
  • 4、同步备份数据至本地服务系统,并保留归档;
  • 5、设定高可用 HA MYSQL、保证数据库故障后的无缝接管;

五、其他需求

  • 1、对各种系统、服务运行日志进行分析,针对性优化系统;
  • 2、根据开发和其他部门要求,完成新系统的构建和二次开发;
  • 3、领导安排的其他事宜;

工作内容

运维工程师详细工作内容

  • 1.设定所有服务器的监控报警机制,并发送报警信息至 js_xlq 和js_zdy@ixdcw.com;
  • 2.设定系统故障后的自动重启 shell 脚本实现和接管机制 nginx 的反向代理存活机制或 Keepalived 检测机制;
  • 3.设定图片服务器的防爬功能,时时关注异常抓取并设定封堵;采用 nginx 的三方插件或自行写 shell 实现;
  • 4、分析 nginx php mysql linux 的访问日志,并把网站、api 访问统计、数据库 0.5ms 慢查询日志、PHP feata error、汇总自动发送到指定人员(使用 python 来是实现分析并发送邮件),关注前段 static 下的图片、css、错误日志记录并发送前段。所有以 show ,list 访问不存在的死链,统计后发送 SEO;
  • 5、数据库的实时备份从备份、每日的完整备份和完整单表备份;并归档到本地;采用主从库设定、binlog 和 shell 来实现;
  • 6、防止 DDOS 和 CC 攻击 WAF 软件部署; 采用 LUA 的扩展实现;
  • 7、优化开发人员环境并开发部署;(采用张宴使用的方式进行)

运维考题

  1. 如何监控一个 ip 访问异常并进行处理

App

IOS 端

海外加速

对于 IOS 应用的审核, 在进行包提交审核的时候经常会遇到加载 Vue 开发页面出现白屏的情况, 遇到此情况我们将 Vue 页面支持全球加速, 如果是 oss , 开启静态访问, 全球访问

服务器使用 aliyun 弗吉尼亚 进行测试

未加速

已加速

[转] BAT 技术评级

P1、P2 入门

1、了解计算机专业的基础知识,懂计算机的基本操作,掌握一门基础的程序语言即可
2、BAT 一般空缺,为非常低端岗位预留

P3 助理

1、熟练掌握一种语言,掌握一种开发环境
2、了解编译器的原理和实现机制,了解操作系统中的内部机制
3、能独立完成复杂任务,能够发现并解决问题
4、在项目当中可以作为独立的项目组成员

P4 初级专员

1、深入了解一门操作系统,掌握某项领域知识的各种思想原理
2、各种经验、技能、技巧掌握下来,学习一些知名的开源项目
3、对于复杂问题的解决有自己的见解,对于问题的识别、优先级分配有见解,善于寻求资源解决问题
4、可独立领导跨部门的项目;在专业方面能够培训和教导新进员工。

P5 高级工程师

1、做基础研究,研究非数值”计算”
2、在专业领域,对自己所从事的职业具备一定的前瞻性的了解
3、对于复杂问题的解决有自己的见解,对于问题的识别、优先级分配见解尤其有影响力,善于寻求资源解决问题
4、可独立领导跨部门的项目;能够培训和教导新进员工;
5、是专业领域的资深人士;行业外或公司内培养周期较长。

P6 资深工程师

1、在某一专业领域中,对于业界的相关资源及水平比较了解;
2、参与部门相关策略的制定;对部门管理层的在某个领域的判断力产生影响;
3、对事物和复杂问题的分析更有影响力。
4、进行创新。对任何一种简单的东西,需要考虑各种各样的需求,以需求来驱动研究;对各种最基础性的查找结构和算法都了然于胸。

P7 技术专家

1、是某一领域中的资深专家;对某一专业领域的规划和未来走向产生影响
2、有较大的贡献。(首先解决问题必须是比较重要的,其次你要比前辈们在某方面有一个较大的提高,或者你解决的是一个全新的以前没有解决过的问题;最重要的是,主要的思路和方法必须是你自己提供的,不再是在别人的思路基础上进行的优化和改进。)

P8 高级专家

1、在公司内部被认为是某一方面的专家或者在国内的业界范围具备知名度和影响力;
2、对公司某一方面的战略规划和未来走向产生影响;
3、在本领域的思想和研究在公司具备较大的影响力;
4、年薪 80-100w,国内约有 2w 人

P9 资深专家

1、业内知名,对国内/国际相关领域都较为了解;
2、对公司的发展做出重要贡献或业内有相当的成功记录
3、所进行的研究或工作对公司有相当程度的影响;
4、年薪 120-150w,国内约有 0.3W 人

P10 研究员

1、在公司内部被认为是某一方面的专家或者在国内的业界范围具备知名度和影响力;
2、对公司某一方面的战略规划和未来走向产生影响;
3、在本领域的思想和研究在公司具备较大的影响力;
4、使命感驱动。

P11 及以上 科学家

1、业内顶尖人才, 对于国际上相关领域的思想/实践都有独到的见解并颇受尊重,比较有名望;
2、对公司的发展做出重要贡献或业内有相当的成功记录;
3、能领导公司相关方面的研究、开创业界一些实践;
4、所倡导或所开创一些做法对公司的未来有深远的影响;
5、年薪 160w+,国内约有 0.1W 人

质量控制

事故分级

事故指的是线上出现的产品质量问题并且对运营造成严重影响的, 或在可预见范围内造成严重影响的.

P0

核心业务重要功能不可用且大面积影响用户

例如:

  • 数据资金错误导致回档
  • 包提交审核, 被拒并导致账号被永久封禁(风险项可预知,且触发)
  • 服务器操作导致的各种的无法服务故障, 并影响大面积用户

奖惩
取消年度考评, 取消年度晋升/提薪

P1

核心业务重要功能不可用,但影响用户有限

奖惩
取消季度考评, 取消本季度中剩余月份奖金, 最长 3 个月

P2

核心业务周边功能不可用,持续故障将大面积影响用户体验

奖惩:
取消当月考评, 取消当月奖金

P3

周边业务功能不可用,轻微影响用户体验
其他高于缺陷却无法列入 P0-P2 级别的事故

例如 :

  • IOS 审核为不可逆审核, 并可能引起账号被永久封禁或者是下架风险的

奖惩:

扣减月度绩效 10+ 分值

缺陷分级

缺陷定义为已上线, 有日志 / 复测证明该问题存在

A 类(B0)

系统偶发崩溃、挂起、非正常关闭等导致系统不能继续运行

包括以下各种错误:

  1. 由于程序所引起的非法退出
  2. 死循环
  3. 因错误操作导致的程序中断
  4. 需求未完成、未实现
  5. 与数据库连接错误,死锁
  6. 服务端出现 400、500 等非正常访问请求
  7. 数值计算错误

奖惩:
扣减 5 分, 超过三次, 本月绩效取消

B 类(B1)

软件不稳定、或破坏数据、或产生错误结果,或部分功能无法执行,而且是常规操作中经常发生或非常规操作中不可避免的主要问题

包括以下各种错误:

  1. 程序接口错误,接口正常返回,但返回的数据格式与数据格式不符
  2. 操作功能无法达到预期
  3. 在小功能项的某些项目(选项)使用无效(对系统非致命的),例如界面正确但数据不符合显示标准
  4. 功能实现不完整,如删除时没有考虑数据关联
  5. 功能的实现不正确,如在系统实现的界面上,一些可接受输入的控件点击后无作用;对数据库的操作不能正确实现,需在测试时候验证数据
  6. 导出报表格式与预期的数据不符,不完整
  7. 轻微的数值计算错误,可能会出现丢失小数据,出现多余小数据
  8. 界面错误(详细文档)

奖惩:
扣减 3 分

C 类(B2)

系统性能或响应时间变慢、产生错误的中间结果但不影响最终结果等影响有限的问题。

包括以下各种错误:

  1. 操作界面错误(包括数据窗口内列名定义、含义是否一致)
  2. 打印内容、格式错误(只影响报表的格式或外观,不影响数据显示结果的错误)
  3. 简单的输入限制未放在前台进行控制
  4. 删除操作未给出提示
  5. 虽然正确性不受影响,但系统性能和响应时间受到影响,例如假死和无响应
  6. 不能定位焦点或定位有误,影响功能实现
  7. 显示格式不正确但输出正确
  8. 增删改功能,在本界面不能实现,但在另一界面可以补充实现。
  9. 滚动条无效

奖惩:
扣减 1 分

D 类(B3)

使操作者使用不方便或遇到麻烦,但它不影响执行工作功能或重要功能。界面拼写错误或用户使用不方便等小问题或需要完善的问题。

包括以下各种错误:

  1. 辅助说明描述不清楚,自行组织的语言且无法描述其目的性
  2. 输入输出不规范
  3. 长时间操作未给用户提示
  4. 提示窗口文字未采用行业术语
  5. 可输入区域和只读区域没有明显的区分标志
  6. 必填项与非必填项应加以区别
  7. 键盘支持不好,如在可输入多行的字段中,不支持回车换行;或对相同字段,在不同界面支持不同的快捷方式
  8. 界面不能及时刷新,影响功能实现
  9. 跳转设置不好或定位错误
  10. 一些建议性和优化性问题
  11. 系统处理未优化
  12. 界面不规范,没有严格按照 UI 图显示并非正确的解决 UI 显示的处理方式

奖惩:
扣减月度 0.5 分

缺陷类型

缺陷分类目的:

  1. 对缺陷产生的原因做深入了解归类,利于测试人员对需求、设计和开发方面技术了解。
  2. 利于后续分析总结,对项目影响项目质量的问题进行总结,推动需求、设计和开发共性问题解决

功能缺陷

经开发和测试确认, 确定权责

  1. 功能缺失、未实现、功能正常使用报错、或出现多余功能;
  2. 执行结果与预期不相符;
  3. 实现的功能与需求定义的不致;
  4. 影响周边系统或模块
  5. 开发设计与需求不符
  6. 业务流程存在逻辑缺陷
  7. 数据库设计存在缺陷,不能满足业务需求
  8. 异常处理有问题或未进行异常处理

设计缺陷

因需求文档缺失, 流程设计不完善等导致的流程不一致的问题, 产品负全责

  1. 实际使用中发现需求存在考虑不完善 ;
  2. 需求不易理解或存在: 二义性;
  3. UI 设计内容与原型图不符或无法展示用户输入数据
  4. 设计流程 (操作流程 )不符合用户使用习惯
  5. 影响周边系统或模块
  6. 设计与通用使用习惯不符
  7. 设计与需求不符
  8. 业务流程存在逻辑缺陷或与现存功能冲突

界面优化

线上出现界面和设计图不符合问题, 经确认之后出现的问题

  1. 错别字;
  2. 统一布局样式(如按钮摆放位置、输入框大小、字体、颜色) ;
  3. 系统页面与设计图不符;

配置缺陷

开发配置导致的问题, 开发权责, 一般于运维/部署相关
配置文档完善与否导致的错误, 测试/运营/产品确定相关权责

  1. 独立安装部署不成功
  2. 配置文件或初始化数据错误
  3. 不同运行环境错误
  4. 后端部署配置缺失或异常

安全相关

[暂不实行]

  1. xss 漏洞;
  2. sq|注入;
  3. 引用不安全第三方组件;
  4. 越权问题;
  5. 登录效验不严格,存在逻辑漏洞

性能问题

[暂不实行] 测试对性能负有 30% 责任, 开发 70%

  1. 接口性能问题;
  2. 客户端性能问题 (web 页面渲染等相关 );
  3. 查询性能效率低

兼容性

  1. web 浏览器及 wap 页面兼容性问题
  2. android 端兼容性问题
  3. iOS 端兼容性问题

功能优化

包含操作易用性, 通用异常

  • 用户操作易用性
  • 输入框末做长度、类型等限制,必填项和非必填项未区分
  • 特定字符未做判断,比如手机号码、身份证号码等

其他

暂时未弄清楚原因的或无法定位问题的及以上原因分类无法包括的;