bxiaopeng / softwaretestingweekly Goto Github PK
View Code? Open in Web Editor NEW软件测试周刊
License: MIT License
软件测试周刊
License: MIT License
当我们在调试 JPA 的时候, 想看最终的 SQL ,一种方式是在 application.properties 文件中把 show sql 的开关打开。但是这种方式还需要手动把参数 ?替换成真实的值,不是很方便。
spring.jpa.show-sql=false
但是 p6spy 这个工具,可以得到一个可执行的 SQL,具体用法请参考文档:https://www.jianshu.com/p/9d1fb06df33b
由于接口测试脚本编写耗时,而且需要持续维护,耗时耗力,使用此工具可以一键生成接口测试脚本.
swagger-ui 接口文档一键生成 jmx 文件供 jmeter 使用.
来源 https://testerhome.com/topics/25722
聊起英语这个话题,老大难了,上学的时候总说 “我是**人,不说英国话,英语不及格,说明我爱国”,也不怎么学,从不张口读,发音不准,又记不住。书到用时方恨少,现在,被它磕绊住了。
做事总要有目标,按照四六级背单词?没那么多精力啊,偶然间发现了一个好东西,JavaSE 的单词本(基于有道翻译的单词本)。
https://blog.csdn.net/weixin_38912070/article/details/112386551
背景
作为一款国民级二手交易App,闲鱼每天都有成千上万的二手闲置商品发布,精准的个性化的商品推荐是促进闲鱼用户快速成交的秘诀。搜索推荐算法的精准和埋点数据的准确性息息相关。一旦埋点数据出现问题,用户侧就会出现推荐商品不准确、过度推荐等问题,同时宏观的交易大盘数据的统计也会有偏差,进而影响整个商品运营策略,因此采取有效的手段来保障埋点质量就成为了闲鱼客户端质量保障的关键的一环。
问题
过去的一年闲鱼客户端在首页、搜索、商品发布等核心场景下进行App体验优化与升级,在客户端快速迭代过程中经常会出现UI改版之后某些关键埋点没有上报、埋点关键字段缺失、埋点字段值不正确等问题,而这些问题在线下测试的时候由于不影响用户体感而被忽略,往往客户端版本发布之后算法或者数据同学察觉到数据异常才会回过头来定位埋点问题,问题修复代价很高,通常会追加客户端版本或者开关降级来解决埋点异常的问题。通过对迭代过程中出现的问题复盘得出来主要有以下的急需解决的问题
•哪些是我们需要重点保障的核心埋点
•如何开展有效的线下埋点测试
•如何提高埋点问题的排除效率
针对以上问题,闲鱼技术质量团队结合自身业务特点提供了一套低侵入埋点质量保障方案
埋点质量保障方案
闲鱼端上承载着数以万计的埋点,且随着业务的增长埋点个数也在不停地增多,而这些埋点由于历史原因都没有沉淀相关的说明文档,依赖开发、数据、产品同学主动梳理埋点数据显然是一件耗时费力又容易出错的事情,所以针对端上埋点质量保障我们的核心**是:通过历史数据的分析和人工干预生成埋点画像(校验规则、值特征),优先保障核心埋点,并提供自动化测试和埋点版本对比来提升埋点数据交付的信心。
null
如图所示为闲鱼端内埋点质量保障方案,埋点数据hook后进行数据的抄送,抄送的埋点数据会分为两部分,一部分样本会交给埋点分析服务提取埋点的Key/Value特征,进而生产埋点的校验规则;另一部分核心埋点会交给验证服务处理,参考已生成的校验规则和人工干预的校验条件会对这部分数据进行逐个校验,最后在版本灰度发布前也会提供埋点的版本比对功能来确定核心埋点是否漏报。
核心埋点梳理
首先需要从成千上万的埋点中圈选出重点保障的埋点,圈选的原则是
•埋点数据缺失/异常会导致搜索推荐算法精准性
•埋点数据缺失/异常会导致大盘统计数据偏差
•埋点数据缺失/异常会导致运营投放策略
满足上述条件的都会被标记为闲鱼客户端核心埋点。前期我们梳理了闲鱼首页、同城、关注、搜索、详情等场景,并通过埋点所属页面(PAGE)、事件标识(ARG1)、事件类型(EVENTID)进行核心埋点的标记,最终在后续的测试中也更侧重于这部分核心埋点,而这部分的埋点的校验规则则是由样本数据分析和人工规则干预得出的。
埋点数据上报
圈选出核心埋点之后,接着需要解决的问题就是如何获取客户端埋点数据。闲鱼端上集成的埋点SDK是通过实时上报通道对埋点数据进行上报,上报后数据经过处理后会最终落到数仓中,所以说要拿到埋点数据可以从数仓中取数据,也可以在端上下功夫。由于数仓取数存在数据实时性不高、数据量大、调用链路长等问题,最终选取了客户端埋点抄送的方案。通过对端上埋点上报通道的hook来实现每一个埋点数据抄送。
例如在Android端我们采用的是AOP切面拦截的方式对开发包的埋点数据进行截获然后通过HttpAPI抄送到数据接收服务。当然采用这种直接拦截代码的方式做数据抄送需要熟悉代码逻辑,做最小化的侵入。除了AOP切面拦截,类似的通用技术方案Frida[1]也是不错的选择。
埋点校验规则
有了埋点数据之后接下来就是补全核心埋点的特征,例如埋点上报哪些字段、字段是必须上报的、字段的值是离散的还是可枚举的、字段在上下文场景中值的特点。后端的数据处理就会根据核心埋点的分布和版本上报数据进行样本的提取,对每个样本逐字段进行检查,并统计Key的分布、Value的分布,当样本数达到阈值之后根据历史Key/Value分布数据就能得出以下的基础校验规则
•Key非空
•Value非空
•Value取值范
上面的基础规则得出之后进一步对数据进行聚类分析,就可以得出以下的场景校验规则
•组合Key条件下Value的特征
例如:通过样本的聚类分析可以推断出类似于“同一次搜索过程中,rn参数必须保持一致”这样的规则
埋点自动化测试
有了数据和规则接下来就需要自动化测试脚本大显身手了。通过手工操作闲鱼App能知道对应埋点触发的时机、页面等信息,因此只要编写自动化测试代码替代人工的点击、滑动、浏览行为就可以做到埋点的自动化验证。以搜索点击核心埋点为例整体的自动化验证过程示意如下
null
埋点的自动化测试可以大幅提高埋点回归的效率,测试同学只需按照版本维护核心埋点自动化用例,就可以在分钟级别完成闲鱼核心埋点的自动化验证。埋点自动化测试解决了大部分的核心埋点的精准验证问题,版本比对则是在自动化之上实现埋点Diff的功能,通过不同版本埋点数据的比对快速检测出新版本中哪些埋点丢了,哪些埋点埋点格式发生了变化,进一步降低人工排除的成本。
null
总结
闲鱼端内埋点质量保障方案对端上侵入较少,通过历史样本数据分析免去了人工主动梳理埋点的工作量,目前梳理出闲鱼端内重要场景(首页/关注/同城/搜索/发布/详情)下的核心埋点共计100+,UI自动化验证整体回归时间由手工测试耗时0.5天下降为到分钟级别,快速的版本比对和可视化的埋点数据展示和筛选也让埋点问题排查变得更加方便。
在未来我们将继续从以下两点来进行方案的整体优化:
•埋点自动化将纳入端上集成卡点之中,即开发同学集成后就立即触发埋点的自动化验证和比对,在集成阶段就提早发现埋点问题。
•自动化深度和用例的可维护性方便也是我们需要努力的方向。
希望我们的自动化手段能让更多技术小二从重复劳动中释放出来,提升数据质量的同时也为每一个闲鱼的用户提供贴心的个性化推荐服务,为每一个闲鱼用户提供更好的购物体验。
Chrome的强大,你探索出了多少呢?
https://mp.weixin.qq.com/s/lAGTkRr5psQ8tKiZcFwSkg
最高境界:帮助你所在的组织改善树立正确的质量观念;帮助所在团队建立起有效预防和发现bug的流程体系与技术栈。
测试的同学应该作为推动者和实践者,把质量意识灌输到每个团队成员的意识甚至是潜意识中去(注意:灌输意识不仅仅是测试同学的责任!)
做测试最高的境界是什么
我们的测试平台上,有各种图表,其实都是有共性的。 从一个例子说起。
基础数据:
统计一班和二班的人数 (表格):
select 班级, count(*) AS 学生个数 FROM table_student GROUP BY 班级:
图表:
柱状图:
饼图:
统计每个老师在每个班级中带的学生个数:
SELECT 班级,老师,COUNT(*) AS 学生个数 FROM table_student GROUP BY 班级,老师
图表:
更进一步的图表:
二维柱状图:
抽象成数据规范:
只要有一份数据,是下面的格式,就可以转换为一份二维表格/柱状图/折线图,而缺少dimension(维度)或者group时,其实就是一份一维表格/柱状图/折线图/饼图。
因此可以规范所有的后端接口都能得到这样的数据,那么前端就一定可以将其展现成一张图表。
[
{
dimension : xx,
group : xx,
value : xx
}
...
]
接口平台里的一维数据:
基础数据:**
统计结果是优良差的个数:
SELECT result, sum(count) FROM score_result_project where result in ('优', '良', '差') group by result
[
{
"value": "4086",
"name": "差"
},
{
"value": "522",
"name": "良"
},
{
"value": "23",
"name": "优"
}
]
更精彩的思考请继续:参考:度量平台开发实践
范围风险:需求变更、测试覆盖程度等
进度风险:工作量估不准、任务依赖造成延迟、人员变更、休假情况等
质量风险:代码质量、测试人员能力等
环境风险:线上环境和数据差异、测试数据准备、测试账号等
外部风险:不可抗力、政策法规、集成方、竞争对手动作等
充分暴露风险,让团队所有成员对当前面临的风险达成一致的认知,并促使团队进行风险的优先级和响应措施讨论。
避免追责,当遇到线上问题,第一重要是快速响应,及时止损;第二重要是问题复盘,避免再犯。如真是测试的疏忽,大方的背锅也没啥,尽快商议应对措施才是正解。
走出追责和背锅的误区,走进互信的良性循环。
测试:线上问题,这锅我到底背不背?
JAVA 语言特点、数据结构
数据库索引和 sql 调优
网络 http 请求
测试用例设计
Linux 命令
自动化测试
性能测试
将近 10 个问题里, n 多技术问题, 好多不会。所以,没有点点点的测试工程师了,起步就是测试开发工程师。
链接
重点:
测试分层:单元测试、模块测试、接口测试;
测试原则;
测试代码结构;
实践技巧
之前要用到nginx都是直接从其他系统复制过来,由于复制过来的nginx还得修改很多配置项,可能还有改错的风险,想着直接安装一个新的nginx更靠谱,本篇文章简单易懂,实操顺利安装,推荐给大家!
https://www.cnblogs.com/xxoome/p/5866475.html
日志对于程序员是不可或缺的,在我们的开发过程中,写完代码需要调试的话,日志是必须的,日志可以帮助我们定位我们的问题,从而更好地帮助我们解决 bug
https://mp.weixin.qq.com/s/oP7cLg0rbU2DRnVD5kvuug
无线端测试平台化最大的优点:
无线端测试平台化可能的难点:
功能模块
├─系统管理
│ ├─用户管理
│ ├─角色管理
│ ├─菜单管理
│ ├─权限设置(支持按钮权限、数据权限)
│ ├─表单权限(控制字段禁用、隐藏)
│ ├─部门管理
│ ├─我的部门(二级管理员)
│ └─字典管理
│ └─分类字典
│ └─系统公告
│ └─职务管理
│ └─通讯录
│ └─多租户管理
├─消息中心
│ ├─消息管理
│ ├─模板管理
├─代码生成器(低代码)
│ ├─代码生成器功能(一键生成前后端代码,生成后无需修改直接用,绝对是后端开发福音)
│ ├─代码生成器模板(提供4套模板,分别支持单表和一对多模型,不同风格选择)
│ ├─代码生成器模板(生成代码,自带excel导入导出)
│ ├─查询过滤器(查询逻辑无需编码,系统根据页面配置自动生成)
│ ├─高级查询器(弹窗自动组合查询条件)
│ ├─Excel导入导出工具集成(支持单表,一对多 导入导出)
│ ├─平台移动自适应支持
├─系统监控
│ ├─Gateway路由网关
│ ├─性能扫描监控
│ │ ├─监控 Redis
│ │ ├─Tomcat
│ │ ├─jvm
│ │ ├─服务器信息
│ │ ├─请求追踪
│ │ ├─磁盘监控
│ ├─定时任务
│ ├─系统日志
│ ├─消息中心(支持短信、邮件、微信推送等等)
│ ├─数据日志(记录数据快照,可对比快照,查看数据变更情况)
│ ├─系统通知
│ ├─SQL监控
│ ├─swagger-ui(在线接口文档)
│─报表示例
│ ├─曲线图
│ └─饼状图
│ └─柱状图
│ └─折线图
│ └─面积图
│ └─雷达图
│ └─仪表图
│ └─进度条
│ └─排名列表
│ └─等等
│─大屏模板
│ ├─作战指挥中心大屏
│ └─物流服务中心大屏
│─常用示例
│ ├─自定义组件
│ ├─对象存储(对接阿里云)
│ ├─JVXETable示例(各种复杂ERP布局示例)
│ ├─单表模型例子
│ └─一对多模型例子
│ └─打印例子
│ └─一对多TAB例子
│ └─内嵌table例子
│ └─常用选择组件
│ └─异步树table
│ └─接口模拟测试
│ └─表格合计示例
│ └─异步树列表示例
│ └─一对多JEditable
│ └─JEditable组件示例
│ └─图片拖拽排序
│ └─图片翻页
│ └─图片预览
│ └─PDF预览
│ └─分屏功能
│─封装通用组件
│ ├─行编辑表格JEditableTable
│ └─省略显示组件
│ └─时间控件
│ └─高级查询
│ └─用户选择组件
│ └─报表组件封装
│ └─字典组件
│ └─下拉多选组件
│ └─选人组件
│ └─选部门组件
│ └─通过部门选人组件
│ └─封装曲线、柱状图、饼状图、折线图等等报表的组件(经过封装,使用简单)
│ └─在线code编辑器
│ └─上传文件组件
│ └─验证码组件
│ └─树列表组件
│ └─表单禁用组件
│ └─等等
│─更多页面模板
│ ├─各种高级表单
│ ├─各种列表效果
│ └─结果页面
│ └─异常页面
│ └─个人页面
├─高级功能
│ ├─系统编码规则
│ ├─提供单点登录CAS集成方案
│ ├─提供APP发布方案
│ ├─集成Websocket消息通知机制
├─Online在线开发(低代码)
│ ├─Online在线表单 - 功能已开放
│ ├─Online代码生成器 - 功能已开放
│ ├─Online在线报表 - 功能已开放
│ ├─Online在线图表(暂不开源)
│ ├─Online图表模板配置(暂不开源)
│ ├─Online布局设计(暂不开源)
│ ├─多数据源管理 - 功能已开放
├─积木报表设计器(低代码)
│ ├─打印设计器
│ ├─数据报表设计
│ ├─图形报表设计(支持echart)
│ ├─大屏设计器(暂不开源)
│─流程模块功能 (暂不开源)
│ ├─流程设计器
│ ├─在线表单设计
│ └─我的任务
│ └─历史流程
│ └─历史流程
│ └─流程实例管理
│ └─流程监听管理
│ └─流程表达式
│ └─我发起的流程
│ └─我的抄送
│ └─流程委派、抄送、跳转
│ └─。。。
└─其他模块
└─更多功能开发中。。
项目地址:github.com/zhangdaiscott/jeecg-boot
GitHub 近两万 Star,无需编码,可一键生成前后端代码,这个开源项目有点强!
智能UI模块主要解决的几个问题:
文章摘要:
稳定性建设是一项系统工程。包括监控,告警,降级,预案,演练,压测,灰度,变更管控,机制建设等。其中监控是整个方案最重要的一环,事前及时预警发现故障,事后提供数据排查问题。
如果单从代码正确性上来说,老方式写法写当然没有什么问题,那唯一的缺点其实就是代码行数比较多,比较繁琐。
https://mp.weixin.qq.com/s/Ea1ADL9GW7m9ikUjFF_HmA
人工智能深度好文,都是大白话,读着高大上。好文章参考
今天“不幸”被老板拉去REVIEW刚结项的项目,结果自然是一顿被批评;不过从总体“收益”来讲还是比较“划算”的!毕竟还是学习到了很多东西,其实我还是比较喜欢这样的REVIEW,因为它可以给自己带来较快的成长!
既然说到了被REVIEW、被批评,那么今天要说的内容自然就是与这个相关的。在此之前我们可以问自己几个问题:
作为测试人员,我们该如何保证质量?
作为项目OWNER,该如何保证质量?
作为一个大型项目的OWNER,该如何保证质量?
作为一个大型紧急项目的OWNER,该如何保证质量?
作为一个大型紧急新接手项目的OWNER,该如何保证质量?
我相信,很多时候这些问题就可能出现在面试当中,尤其是非技术流,偏项目管理的岗位面试中。虽然说我是偏技术流的,但也避免不了被问到这样的问题,甚至我在面试别人的时候也会问到这样的“奇怪”问题。
无形的“被动”
作为测试人员,我们经常会发现自己的工作非常的“被动”。比如:被动的等着开发提测的延期;被动的背起线上的bug;被动的要保证100%的项目质量(即使开发一点自测都不做)。
如果你“摸”胸而论,你还会觉得这些都是作为测试应该有的结果么?来自你内心深处的答案肯定是否定的,当这些事情被摆在明面上的时候,很多人都会“情不自禁”的接受了!
为什么会这么被动?是因为我们从根本上没有明确测试的职责!我们不是应该是被延期的对象,不应该是背锅侠,更不应该是保障质量的唯一能力者。
开发自测VS测试人员测试
前几天看到一篇文章写的很好,讲的就是开发自测与测试人员测试的本质区别,并且我还转发到朋友圈了。文章中打了个比方来形容两者的区别。
如果说质量是一张平面,平面中有一个圆圈,开发自测就是等于在圆内做检查,而测试人员的测试则是在圆外做检查。即一个是在既定/有限的区域内保障质量,一个是在未知/无限的区域中探索质量问题。
所以你就能理解,为什么需要开发做单元测试、需要TDD、需要自测,因为这本来就是他的本质工作。如果一个开发人员写完一个功能后,自己都没有完全跑通就提交测试,那么肯定是一个不合格的开发人员,是需要慎重对待的。
同样你也能理解,为什么开发自测了,测试人员还有需要存在的价值。测试不仅是开发的DOUBLE CHECK,更是对未知区域隐藏bug的探索,也是对非功能性需求的覆盖测试。
不存在的“完美”质量
测试人员的**往往会被带入常识性的误区。比如:作为专业的测试人员不应该有bug;只要是质量问题就是测试的锅。其实这些都是不对的,只有没被发现的bug,没有0bug;所以我们不需要追求100%的质量,这个是不存在的。天塌下来还有“高个子”顶着,项目出了质量问题,第一责任人首先应该是最高负责人。
所以有bug或者有缺陷的项目是可以接受或者上线的,但前提一定是这些已知/未知缺陷是在当前可接受范围内。比如:线上大促,肯定不能是性能有问题;参加大赛,肯定不能是流程中断问题。
如果说测试也遵循着2/8原则,花20%的精力就能发现80%的bug,那么我肯定不会把剩下的80%的精力再去发现剩下的20%的问题。首先产出比不高,更重要的是它存在很大的风险。所以剩下的80%的精力一定是思考如何更好的保证正常功能的稳定性,思考各种极端环境可能出现的问题及其对应的预备方案。而剩下的20%的问题则属于长尾问题,需要长期不断的优化和打磨,可能即使你“毕其一生”也发现不完!
技术保障“质量”
严格来讲,技术保障质量是个伪命题。因为研发/测试人员本身都保障不了质量,技术又怎么能保障质量呢?当然这并不妨碍我们在质量保障过程中使用技术手段,毕竟技术可以提高测试效率、增加测试覆盖率、增强测试手段。所以技术在质量保障过程中还是有它独特的价值的,并且不同项目中体现的价值也会有差异。
技术保障适用于那些测试场景重复且固定流程的改进,适合那些机械且重复组合的场景;技术保障适用于我们平常没有时间或者覆盖不到的场景,比如:单元测试、API测试;技术保障适用于那些手工无法测试的场景,比如:建造大量的测试数据,控制程序的微观操作,测试场景的改造和测试内容的欺骗。
技术保障的方式有很多种,在不同的团队和项目组中达到的效果也不尽相同;在应用好的项目中它是利器,在应用不好的项目中它就成为了鸡肋。因此还考虑使用技术来保障质量的之前,需要深刻思考它真正能解决的问题和期望能达到的效果,甚至可以先使用DEMO来进行一段时间的适用,在拿到实际数据之后再评估是否真的需要技术改造。
什么是质量
质量从来都不是测试说了算,也不是老板说了算,而是用户说了算。你认为不是问题的问题,对于用户可能是不可接受的bug;而你认为是问题的问题,对于用户可能根本就是不是问题;你认为不会出现的问题,在用户那可能就会真实的出现。
质量可以是项目/产品的验收标准,包括功能性、非功能性的;同时质量也是用户的一种综合体验,越多的人觉得系统/产品好用,就说明质量越高。而那些小部分人认为不习惯用,和用户不关注的bug都应当不在质量的范畴之内!
质量不是说线上一定不能出bug,质量是长期稳定的保障服务正常运行,保障用户体验流畅,保障用户留存率,保障业务收入的一种能力。不影响这种能力的线上bug,可以视为低价值的bug;这类bug不是不改,而是应该在合适的时间里去修复它。比如:项目组有额外精力的时候。
质量是一种自顶向下的态度,为什么微软、谷歌的项目质量做的比较好?那是因为它们是技术性公司,从顶层设计时就会考虑质量,不仅仅只是考虑功能的开发;所以一个完整的项目/系统设计,一定是从一开始就确定了如何去度量质量,如何去执行测试,如何去覆盖场景,如何协调团队的整体资源分工合作。
如果把测试当做足球守门员,那么开发就是后卫,项目管理者就是中场,高层领导就是前锋。虽然位置不同但是目标是一致的,质量保障就像防守一样需要整个团队的通力合作才能做到更好。如果所有问题都直接漏到测试这一层,那么“守门员”就会被打成筛子,即便他使出了“洪荒之力”。
质量体现在可控的流程之下,有些人可能会觉得有些系统就是没有质量问题;比如:银行系统为什么不出错,航天系统为什么不出错。实际情况真的是这样么?当然不是。新闻偶尔也会爆出ATM机可以取出超额的现金,电影里也会演绎利息余数的bug,NASA也有发射失败卫星失败的时候,导弹也会有击中错误目标的情况,甚至某飞机近期接二连三的爆出飞行事故问题。
但是当我们反过来思考的时候,你会发现虽然这些系统也会有一些意外的情况,但是它们发生的概率还是非常小的,一旦发生就会是新闻级的现象。而之所以这些系统的质量在普通人眼里觉得非常高,根本原因是在于这些系统都是固定的流程系统,每一个操作、指令、设备都是有严格要求的,不是你想怎么操作就怎么操作的。而我们日常所测试的系统则是用户产品,所以你懂的!
当我们在谈“质量”时
是保障80%,还是追求100%
是追求0BUG,还是追求不出错
是测试来背锅,还是领导来负责
质量属于测试,还是质量属于团队
质量是常规功能,还是用户综合感受
质量是穷举未知范围,还是确定固定流程
原文地址:为什么你技术这么牛逼,别人却不配合你?
重点:
一个人的事业成就、生活幸福,很大程度上,取决于你的横向领导力。
如何提升自己的横向领导力?
1、启动:从清晰的目标、行动方案开始;
2、拉人:组建一支能够完成目标的团队;
3、推动:没有权利,如何推动项目;
4、冲突:如何处理执行过程中的分歧;
5、激励:项目结束,如何激励团队;
基本都是有趣的内容,可以作为周刊里面的图片部分。
1、这个需求的价值是什么?
2、我们的目标用户是谁?用户量多大?
3、这个功能解决了用户什么痛点?有数据支撑吗?
4、原型图画了吗?设计文档写完整了吗?
5、设计文档确定不改了吧?行,我给你排期
6、你就告诉我,要抄哪家吧
7、我这里没问题了,让项目经理去立项吧
8、这个需求对架构影响蛮大的,拉上架构师再讨论下
9、工作量主要在前端,让前端一起评估下吧
10、这个功能很有创新性啊,让老板也来头脑风暴一下吧
11、假装同意后,拒绝
12、若有所思后,拒绝
13、反问后,再拒绝
14、然后,开始踢皮球
15、Never Say No
**答:**有些同事在测试几轮之后,功能稳定了开始介入性能测试,这时才发现性能根本支撑不了预期值。这个时候开发再回头进行系统调优,如果事先选的架构能支撑就好,如果不能达不到预期值,后面讨论或者请教高手发现原先的架构缺陷,再调整架构代价就非常大。基本导致前期的功能测试成果作废。其实各个阶段都有事情做。需求阶段可以整理,评审出性能需求,评审需求可行性时就考虑好数据量和用户量。设计阶段--对预估的需求做设计,举个例子。背景:我们现在使用的是mysql数据库(公司去oracle化),我们要从一个5000W的一个数据表的6个不同查询维度查询数据,比如说城市、行业、地址类型、爱好、性别、时间范围。这样对于mysql的查询常见的优化设计可能是分表、建立索引,但,对于这个场景就不好处理了。数据耦合强,没有办法分表。索引,组合索引太多。后面的处理办法是用mongodb、nosql的方法解决。对于编码和测试阶段可以这样去分不同阶段做不同事情。
编码阶段,可以提出需要,让研发通过单元测试(开多线程)的方式进行压力测试。进行一些单元压力测试测试阶段---测试阶段也有策略的,建议先做一下单一场景单一用户的性能测试。常常会遇到有些同事在没有压单个场景的情况下,就进行负载测试,到处定位瓶颈,最后发现单一用户单一场景都是问题。这就是绕了一圈回到了起点。对于不同类别测试后面会专门的chat介绍。
**答:**获取性能需求,可以一下步骤:
比如业务人员很多,底层给中层、再给高层。
**答:**瓶颈分析几大原则和几个关注可以参考:
答: 我个人是认可的,但我们要具体分析一下。为什么要参数化,更多的人会是是为了模拟真实情况。其实大家想问的是,什么才叫真实情况。有人会说是用户的实际场景。我个人认为这是表面现象。真实情况应该是:能模拟磁盘、CPU、内存的真实情况,才是我们测试人员想要的真实情况。 业务的真实情况最后都会变成对资源的消耗情况。
主要考虑点有:
**答:**首先,性能是设计出来的不是被测试出来的。这个文章中有提到。因此一个好的性能需要做好前期的性能可行性设计。没有这个流程的同学,建议研发流程中加入,性能可行性设计。给出现状(使用工具查看现状):js性能工具: JSLitmus、jsperf、chrome浏览器的profile等。可以检查网页性能情况比如chrome的profeil,操作简单,录制+停止。
可以用工具看到js大小,加载速度等,还可以看看研发的代码。要让研发动起来就的找方法:js常见的优化方法:建议动静分离、建议压缩、建议缓存、建议版本标示、文件合并、方法抽象、避免全局、解耦html和css,具体方法很多。动静分离是常见的。就是把,js、图片、css等静态文件放到不同的服务器上。js由于是静态资源,可以做动静分离,来减轻服务器压力。js做缓存,js由于版本特征明显,需要做好版本标示,保证不会由于缓存带来功能问题。tags可以通过代码或设置中间件如gizp压缩(压缩登记等),其实不光js前台的图片等都有很多优化方法,后面的chat会提到。比如nginx中间件,设置nginx.cfg就能压缩。可以买一本js性能优化的书看看推荐《高性能JavaScript》。
**答:**覆盖率避免漏测:
**答:**场景设计、用例设计、性能分析在后面的chat有专门的分享,一下子说不完整。我把主要的提一下:一把性能测试的关键字段都列出来如:参数化、关联、集合点、思考时间、虚拟IP、负载机请求数、带宽要求、参数化策略、集合点策略等,每一项都写清楚。其实这个同漏测有很大关系:
这就是一个常见的模板,把容易出的问题都设计上去了。所以拉80%的时间做设计,20%的时间做执行。当然所有数据的填写都是基于调研的。所以性能测试应该开始于调研的时候,而不是测试的时候。测试指标的指定是在调研后同产品或需求或业务制度出来的。一定要有明确的性能指标在进行测试,才会事半功倍。所以指标不明确是团队需要改变的地方。
**答:**总原则:以目标位出发点,不要受方法和工具限制。在回到为什么需要工具,工具帮我们在有限资源下,提升效率和生产力:有限制条件,有限资源。
工具与开发比较:
但是要受下面条件限制:
好的辅助工具可以是这样的:有功能开关、可以记录日志、原子性强(比如单元级别的性能测试,能去除垃圾时间,记录业务其实时间,可以记录日志)、针对性强,用推广可能(测试kafka性能、测试redis性能工具类、测试MQ推送与消费)。
答: 时间安排其实前面都有表述,应改能解决这个问题。性能测试的频率根据业务场景需要就测、评估需求的时候,发现有性能要求就计划做,但建议主要功能每隔3个小版本,关注一下业务量,业务量快达到预估值时进行一次,另外要考虑业务高峰期,比如双11、双12、618、春节等,建议之前都做一次。当然不同行业有不同的高峰期。
**问:**每次性能测试的内容都是一样的么?在性能测试的设计和选择上需要主要考虑哪些内容?
**答:**不一样,要根据目标来定。比如,产品要路演,可能只需要单个用户响应速度OK,就可以了。如果现在换成做促销,这个时候就好考虑同时有多少个用户来请求了。那么场景的设计、参数化策略也不一样了。又比如说,新功能是大数据量下载,这个时候就要对下载做功能测试,可能是多用户并发需求;有可能是少用户,大数据量,比如要下载100W条记录的数据。当然要看研发如何实现了,是后台分批压缩。还是定时任务完成。这个同研发实现有关。这也是为什么花一次chat来给大家讲性能测试目的,其实性能设计就是以目的出发的。
可以考虑一下几个方面:
**答:**脚本一定不要太长,能抽象一定抽象,太长自己看不到逻辑关系。所有我写脚本都会先写伪代码。建议大家也这么做,先设计表格,依照表格写伪代码。比如刚刚的场景用例设计表格。文字最好懂,代码不易懂。然后能抽象出去的就抽象出去。需要加的关键点都在场景设计和用例设计时一表格的形式列出来,专家也好评审。对于接口测试,你的思路是对的,我们可以拆解,但接口测试代替不了页面测试。
**答:**这个需要一定的换算标准。当然有些土豪公司就是一比一的设备来进行测试。测试的配置是否与生产一致。如果测试的配置与生产一致的话。可以按照乘以它的百分比,咱最后再乘以70%。这样的话就建议提服务器的人通常同配置,这样便于你计算。如果没有这种等比例的配置,算起来就比较麻烦。服务器型号不同,没有关系,但CPU的核数,以及CPU的频率以及内存。包括你的中间价,你的网络。建议越接近的配置最好。
答: 可以让研发做一些单元压力测试。完善后再做,不建议用lr,可以换jmeter试试。
**问:**性能测试有什么好的自动化方案吗?
**答:**目前我们的做法是和一些持续集成工具或者是自己的写一些脚本串联。当然,可以试着写个平台,包括调度、监控都做了。成熟了在变成黑盒之前建议都白盒。
**答:**可以先做一部分,比如说你先解决,性能测试监控指标,回传和展示。数据库的问题和建议进行数据库相关设置。比如说慢sql,比如spitlight工具。慢sql会记录所有系统查询较慢的sql语句,根据语句找到相应代码进行优化。根据语句,找到相应代码进行优化。
不同的用户有不同的偏好,不仅对于商品,对于UI也是同样如此。淘系会场的智能UI模块由此应运而生。在目前的淘系会场中,所谓的智能UI指的是借助AI提供界面千人千面的解决方案,给不同的用户展现不同的界面。在今年的双11中,智能UI模块成为了会场模块的主流方案之一,在本次双11大促中覆盖了300+的会场,使得会场除了在商品推荐上做到个性化之外,还实现了UI层面上的千人千面的个性化能力。
本文将从零基础开始学习JMeter工具,文章主要包括JMeter基础知识、JMeter最简开发流程、运行与监听、JMeter元件库、脚本开发等方面讲解JMeter性能测试工具。
包括工具介绍、安装、相关工具安装、目录介绍、体系结构介绍、运行原理介绍等,有一定基础的同学可以跳过。
虽然叫JMeter最简开发流程,其实包含了性能测试中的常用关键字,即录制(其他工具录制导入、JMeter录制导入)、参数化、关联、事务、集合点、检查点等。
运行场景中主要介绍线程组、GUI运行、非GUI运行,远程运行、JMeter自身性能参数配置;以及常见的报告产生方法
将介绍最迷惑初学者的元件运行顺序、常见元件详解、各类元件总结分析与简述。
将针对常用的采样器进行讲解主要有:BeanShell、FTP、JAVA请求、JDBC请求、JUnit请求、SOAPUI接口测试、RESTFUL接口测试等。
Apache JMeter是Apache组织开发的基于Java的压力测试工具。
用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域。 它可以用于测试静态和动态资源,例如静态文件、Java 小服务程序、CGI 脚本、Java 对象、数据库、FTP 服务器, 等等。
JMeter能够对应用程序做功能/回归测试,通过创建带有断言的脚本来验证你的程序返回了你期望的结果。
JMeter Windows下载地址:
http://mirrors.tuna.tsinghua.edu.cn/apache//jmeter/binaries/apache-jmeter-3.1.zip。确保已经安装JDK1.7以上版本。
设置环境变量:
java -version
JMeter Linux下载地址:
http://mirrors.tuna.tsinghua.edu.cn/apache//jmeter/binaries/apache-jmeter-3.1.tgz
解压:
指定path目录:
安装完成后运行,验证安装是否成功。
badboy不能发散,必定是一个工具,不能三言两语搞定。如果有同学感兴趣,后面可以开专门的chat来聊一聊badboy自动化测试工具。
可执行文件目录
文档目录。api:api文件以及css和图像样式
扩展插件目录,目录下的文件提供了对ant的支持。
所用到的插件目录,里面全是jar包,JMeter 会自动在 JMETER_HOME/lib 和 ext 目录下寻找需要的类。
lib目录下的ext子目录是jmeter的核心jar包;用户扩展所依濑的包不能直接放到lib下,要放到lib/ext下(注意最新版本是这样,之前个别版本可能反过来,所以很多同学两边都放,两边都放好处在于一定OK,但坏处在于当用户误操作时可能导致两边版本不一样,不好定位问题)。junit子目录是放junit脚本的。
☞注意: 无法识别 zip 格式的包文件,所以需要的包文件均要求以 .jar 结尾。
usermanual子目录下是jmeter用户手册,尤其是component_reference.html是最常用的核心元件帮助手册。
讲JMeter结构前,先看看大家常用工具LR的结构:
LR主要由:脚本产生器、负载控制器(含调度、监控)、压力产生器、分析器组成。脚本产生器负责生产用户代码模拟单个用户以及为模拟多个用户做准备;负载控制器用于控制压力产生器的运行,并收集测试情况、性能计数等;压力产生机主要负责模拟许多用户对服务器进行测试;而分析器主要通过图表、表格分数测试情况用于测试者产生测试报告。
下图为JMeter核心结构关系图,解释了性能核心关键字所对应的元件,以及个元件的位置关系。 整体来讲:JMeter主要由以下4部分组成:一部分负责模拟,一部分负责验证,一部分负责收集结构,一部分负责周边。各部分用途见后面分解:
模拟部分:取样器、配置元件、控制器、定时器、前置处理器、后置处理器、线程组。模拟部分线程组用来建立线程池,多线程运行其他模拟、断言、监听部分;配置元件主要用来做一些数据准备,通用请求准备(如设置一些默认值HTTP请求的、JAVA请求的);控制器主要处理逻辑关系如循环、分支、交替、事务等;定时器用于处理思考时间、集合点、随机时间等工作;前置处理器用来对请求前的数据进行处理(如JDBC请求前的数据准备等);后置处理器用来对请求返回后的数据进行处理(如关联)。
验证部分:断言。断言是测试的精髓,用于判断返回值与预期一致。
收集和展示部分:监听器。是用来收集数据和展示数据(如:测试报告)。
周边部分:工作台(可以防止备用元件、抽象的模块等)。
JMeter分布式运行原理图
控制机:(调度与收集)
负载机:(Agent、多线程、脚本产生器)
测试计划是用来管理整个测试的,计划和线程组都可以理解为容器,是用来放东西的。测试计划可以用来管理测试套、测试工程、测试包等。
一个测试计划至少一个包括:1个测试计划、1个以上线程组、1个以上取样器、1个以上监听器。
录制、参数化、检查点、回放。
从badboy File菜单中导出JMeter脚本,使用JMeter直接打开。
添加查看结果树监听器让执行结果可见。
修正断言,断言可能在超级链接、HTML元素大小写变化等方面会发生变化,需要回复修正。
增强JMeter测试计划可读性。
JMeter-【工作台】-【非测试元件】-【HTTP代理服务器】中配置代理。
为浏览器网页访问添加代理
清空浏览器缓存、清空浏览器主页(为什么)。
缺点:
试着访问https://www.baidu.com。证书位置$JMeter_Home/bin/.crt。
放弃使用录制方法进行性能测试。
实例:查询一个城市的天气预报。
使用抓包工具观察用户页面请求所产生的请求列表,筛选最核心的(不然一些css/js/imag一般情况下可以忽略)。具体思路如下:同抓包发现,查询一个城市的天气是先通过查询城市代码、然后通过城市代码查询天气预报。
第一个Http请求:
Http信息头管理器:
Referer:提供了Request的上下文信息的服务器,告诉服务器我是从哪个链接过来的。 由于服务器有限制,因此必须要告诉接口你是从他希望的服务器过来,不然你可能得不到想要的数据。
响应断言:
我们想返回的数据中包括我们想要的结果。
断言结果:当断言失败时,断言结果会把失败原因给指出来。
查看结构树:
如果使用单元数据,用户可选用“用户自定义变量”进行数据引入。
用户自定义变量:
继续使用以上用例,进行简单的参数化,使用csv Data setConfig引入多样的数据,这样就可以在线程组中设置循环运行或多线程运行。
csv Data set Config:
后置处理器——正则表达式提取器:
第二个HTTP请求:
http://www.weather.com.cn/weather1d/10101010007A.shtml#search
10101010007A使用正则表达式表达的变量进行替换:
如果对正则表达式不了解的同学可以下载一个正则表达式测试工具,如:RegexTester。
用于增强用户编写的脚本:
生成后作为变量使用:
函数助手脚本为什么会失败?明明是查询的城市是北京,为什么断言变成了上海。
看看这个代码为何会成功,思考为什么?(具体原因后面讲述元件运行顺序的时候会重点说明。)
场景设计
通过【线程组】实现并发。同时去执行相同的一批次任务。每个线程之间都是隔离的,互不影响的。一个线程的执行过程中,操作的变量,不会影响其他线程的变量值。
Delay Thread creation until needed: 默认情况下,测试开始的时候,所有线程就被创建完了。如果勾选了此选项,那么线程只会在合适的需要用到的时候创建。
Ramp-Up Period:线程启动的时间,下图的线程配置,多少个线程,多长启动时间(秒),每个线程执行多少次循环。那么每秒会启动一个线程,每次循环执行一个请求。
当线程执行取样器失败的时候,要执行的策略选项:
如果不想立即执行执行,可以通过调度器控制测试执行的开始时间和结束时间。
分别:运行、忽略所有暂停、停止、关闭线程、远程运行、远程停止、远程下线。
远程运行步骤:
1)修改设置控制机jmeter.properties文件,比如远程机的地址为192.168.0.102。
2)运行远程机的jmeter-server.bat批处理文件。
3)在控制机上运行远程按钮。
使用非 GUI 模式,即命令行模式运行 JMeter 测试脚本能够大大缩减所需要的系统资源。
1)需要设置PATH环境变量把JMeter软件目录囊括进去。 如:
2)命令行jmeter -n -t testplanFilename -l listenerFilename
如:
这次我们可以清晰地看到每个线程的执行情况。这里是我们使用非 GUI 模式运行测试脚本时可以使用的一些命令:
例如:
执行结果可以使用 GUI模式下的聚合报告查看,比如你想要看 logfile1.jtl 的报告,可以打开 JMeter GUI 界面 ->测试计划 -> 添加线程组 -> 添加聚合报告 ->点击"所有数据写入一个文件"下的 "浏览..."按钮找到你刚生成的jtl文件就可以对执行结果进行直观分析了。
从文件查看聚合报告:
Jmeter是运行在JVM之上,因此需要设计到JVM相关配置。
jmeter.bat配置取一段一起学习:
set HEAP: 设置JVM堆大小,-xms(初始),-xmx(最大堆大小),-xmn(年轻代,官方推荐年轻代大小是最大大小的3/8)。
set NEW: 设置年轻代大小-XX:NewSize设置初始化大小,-XX:MaxNewSize年轻代最大内存。这个设置云-xmn有重复,一般使用-xmn来设置。年轻代分Eden区和Survivor区。
set SURVIVOR: -XX:SurvivorRation=8,设置Surviovor与Eden区大小的比值。由于surviovor有两个,所有比值为2/(2+8)=1/5。Eden占8/(2+8)=4/5。
set TENURING: -XX:MaxTenuringThreshold=2,年轻代晋升年老代周期(也就是经过多少次GC还存活)。
set PERM: -XX:PermSize,持久代大小,如果要对持久代进行垃圾回收就设置:-XX:+CMSClassUnloadingEnabled。
set DUMP: -XX:+HeapDumpOnOutOfMemoryError,设置当内存溢出是Dump内存信息。
summary Report
aggregate Report聚合报告
元件运行顺序与作用域
元件的运行顺序和作用域是JMeter最精髓的东西,当然也JMeter优缺点的体现地,感兴趣的同学可以重点看看提供给大家的汇总表。
元件执行顺序:"配置元件config elements" 、"前置处理程序Per-processors" 、"定时器timers"、"取样器sampler"、"后置处理程序post-processors" 、"断言assertions" 、"监听器listeners" 。
元件作用域:配置元件,影响作用域内所有元件;前置处理程序,作用域内每个取样器之前执行;定时器,作用域内每个取样器有效;取样器,无作用域;后置处理程序,作用域内每个取样器之后执行;断言,作用域内。
每个取样器执行后的结果校验;监听器,作用域内每个取样器的信息并呈现;逻辑控制器,作用域于子节点取样器和逻辑控制器。父节点不是取样器,作用域是其父节点下其他所有后代节点(子节点和其下的所有节点)。
元件全局分析:
作用域与顺序:
实例分析
详解常见元件库
对于一些HTTPS协议的系统需要在启动代理后,安装JMeter/bin下的证书,才能使用代理服务器,如果手机的录制,需要把设计手机的代理服务器、端口,并在手机段安装证书。
上图中1/7/8条需要单独说明:
Prefix:对每个录制的http请求的前缀命名,默认为空,则录制的请求会按照数字递增的方式进行命名。
http请求的执行引擎,可以通过修改jmeter/bin下的jmeter.properties更换。
每次清除cookies,每次线程组启动时都会清除cookie。
HC4CookiesHandler广泛用于APP,HC4CookiesHandler是用于支持HttpClient4的,而HC3CookiesHandler是用于支持HttpClient3的。
此规格忽略所有Cookie。被用来防止HttpClient接受和发送的Cookie。
头信息管理,常见的有:User-Agent、Connection( 允许客户端和服务器指定与请求/响应连接有关的选项如:keep-alive)、content-type、Accept、Cookie、location302重定向地址信息、Cache-Control。可以通过抓包工具、或查看录制的脚本、察看结果树找到相应的解释。
用来规范代码。
察看服务器返回信息、请求信息、采样信息。
文中使用的正则表达式测试器(RegexTester):下载地址
若在超时时间内,性能测试并发场景设定的并发样本数量未达到,则jmeter认为超时,会立即执行并发。
CSV DATA SET CONFIG
以下是CSV Data Set Config各个参数的简要说明:
什么是Bean Shell?
BeanShell的用法:
在此介绍下BeanShell Sampler的用法,其它的beahshell可以类推。在此我们使用beahshell调用自己写的工具类,工具类实现了求三个数相加之和的功能:
**
JMeter在它的BeanShell中内置了变量,用户可以通过这些变量与JMeter进行交互,其中主要的变量及其使用方法如下:
用于intenet上文件的双向传输。需要兼容不同的操作系统,需要遵循相同的协议;与FTP默认设置一样只是多了用户名和密码。设置与"FTP默认设置"基本一样只是多次用户名和密码。
端口号不填写时默认为21:
☞使用二进制与文本传输区别
ASCII 方式和BINARY方式的区别是回车换行的处理,binary方式不对数据执行任何处理,ASCII 方式将回车换行转换为本机的回车字符,比如Unix下 是\n,Windows下是\r\n,Mac下是\r。
ASCII 方式下会转换文件,不一样的系统有不一样的行完毕符,unix系统下行完毕符是一个字节,即十六进制的0A,而ms的系统是两个字节,即十六进制的0D0A所以当你用ascii方式从unix的ftp server下载文件时(不论是二进制或许文本文件),每检测到一个字节是0A,就会自动插入一个0D,所以假设你的文件是二进制文件比如可执行文件、紧缩包什么的,就肯定无法用了。
假设你的文件就是unix下的文本文件,你用ascii方式是正确的,要是误用了binary方式,你在windows上看这个文件是没有换行的,内部是一个个的黑方块。普通来说,咱们最好都用binary方式,这样可以保证不出错。假设有文本格式转换的疑问,即unix格式的文本和dos格式的文本
Get下载、Put上传。如果是匿名用户也必须填写anonymous
Java请求带有两个java请求类:JavaTest和SleepTest。
核心步骤
实例
新建java项目并引入Jmeter jar包和Junit Jar包,新建需要的包和类:
准备需要测试的代码,如新建一个文本文件并写入内容:
Junit测试代码
实现JavaSamplerClient接口:
新建Junit测试:
打jar包,并放入jmeter/lib/ext下:
在JMeter中进行测试:
工作中需要对数据库进行测试,比如要看看1个sql的并发性能。
准备表:
常用步骤
JDBC连接池设置
事务的ACID:A原子性、C一致性、I隔离性、D持久性。
先理解一下:
mysql数据库:无需引入其他数据库驱动jar包,但要注意末尾别带了空格如:“com.mysql.jdbc.Driver ”。
sql server 数据库:下载sqljdbc4.jar 放到 jmeter根目录的lib目录下。
oracle数据库:将oracle数据的安装目录下面的\product\10.2.0\db_1\jdbc\lib\ojdbc14.jar 放到jmeter根目录下的lib目录下。
数据库URL:
JDBC请求
query Type查询类别:
其他参数:
JDBC请求实例
1)为查询语句定义入参
方法一:使用用户自定义参数:
方法二:使用‘占位符’:
☞注意:如果使用Select Statement只能使用变量,不能使用‘占位符’;如果使用Update Statement只能使用变量,不能使用‘占位符’;Callable Statement可以使用‘占位符’和变量定义。
2)使用commit语句时(连接配置不能自动提交)
3)使用rollback语句(连接配置不能自动提交)
soapui工程可用在这里下载:https://git.oschina.net/giftboys/WebServiceSample.git。
通过WSDL方式取得地址等信息,如:
取得请求的XML,测试同时可用向研发索取,或者通过soapui等工具取得。
参数化或变量后的请求:
察看结果树:
通过WADL方式取得地址等信息,如:
取得请求的XML,测试同时可用向研发索取,或者通过soapui等工具取得。
参数化或变量后的请求:
察看结果树:
通过WADL方式取得地址等信息,如:
取得请求的XML,测试同时可用向研发索取,或者通过soapui等工具取得。
参数化或变量后的请求:
察看结果树:
本文就到这里了,这个假期很充实!
转载:https://gitbook.cn/gitchat/activity/58d70a9f77508ce666dbe12a
线下环境为何不稳定?怎么破
文中摘要:
文章摘要
任何一个管理工具被发明出来,它的初衷都不是要毁掉一个团队,KPI也不例外。
1、管理层不深入业务,只盯KPI
2、KPI跟绩效强绑定
3、用KPI量化所有目标
4、不重视价值观
5、不再关注顾客
6、忽略产品创新
毁掉索尼的不是KPI,而是早已缺乏创业激情的管理层、日益涣散的员工、被抛弃的创新文化。
同样,毁掉百度贴吧的也不是KPI,而是“为了追逐短期利益......逐渐被挤压变形的价值观......在业绩增长目标之下,被抛到九霄云外的用户体验......”
总之,不论KPI、OKR、平衡记分卡,还是360度考核,工具本身无好坏之分。关键在于,是否适合企业现状、是否匹配企业的管理理念、是否实施推广得当。
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.