C-print

如何打印下面的字符?

$
##
$$$
###
$$$
##
$

示例 1:

int main()
{
char array[] = {'#', '$'};
for (int row = 1; row <= 7; row++) {
for (int hashNum = 1; hashNum <= 4 - abs(4 - row); hashNum++)
{
printf("%c", array[row % 2]);
}
printf("\n");
}
}

C - Score Input Sort Show

#include "stdafx.h"
#include <stdio.h>
#define N 5
//Score Input Sort Show
void input(double[]);
void sortAsc(double[]);
void sortDesc(double[]);
void show(double[]);

int main()
{
double scores[N];
input(scores);

printf("[SORT ASC]\n");
sortAsc(scores);
show(scores);

printf("[SORT DESC]\n");
sortDesc(scores);
show(scores);

return 0;
}

void input(double socres[])
{
int i;
for (i = 0; i < N; i++) {
printf("Please enter %d student's score: ", i+1);
scanf_s("%lf", &socres[i]);
}
}

void sortAsc(double socres[])
{
int i, j;
double temp;
for (i = 0; i < N - 1; i++)
{
{
for (j = 0; j < N - i - 1; j++)
{
if (socres[j] > socres[j + 1])
{
temp = socres[j];
socres[j] = socres[j + 1];
socres[j + 1] = temp;
}
}
}
}
}

void sortDesc(double socres[])
{
int i, j;
double temp;
for (i = 0; i < N - 1; i++)
{
{
for (j = 0; j < N - i - 1; j++)
{
if (socres[j] < socres[j + 1])
{
temp = socres[j];
socres[j] = socres[j + 1];
socres[j + 1] = temp;
}
}
}
}
}

void show(double scores[])
{
int i;
printf("********************************************\n");
printf("Chinese\tMath\tEnglish\tPhysics\tChemistry\t\n");

for (i = 0; i< N; i++)
{
printf("%.2lf\t", scores[i]);
}
printf("\n********************************************\n");
}

C-Language 计算图形的面积

#include "stdafx.h"
#include <stdio.h>

/*
计算图形的面积:
1. 圆的面积 = π * radius * radius
2. 矩形面积 = weight * height
3. 三角形面积 = 1/2 * weight * height
@author Xianpeng Shen
*/

double calcCircle(double);
double calcSquare(double, double);
double calcTriangle(double, double);
int validate(double);

int main()
{
int choice; // 用户选择
double area; // 图形面积
double radius; // 圆半径
double weight, height; // 图形的宽和高
printf("1. 圆\n2. 矩形\n3. 三角形\n");
printf("本系统支持三种图形面积计算,请选择:");
scanf_s("%d", &choice);
while (choice > 3 || choice < 1) {
printf("只能输入1~3整数,请重新输入:");
scanf_s("%d", &choice);
}

switch (choice)
{
case 1:
printf("请输入圆的半径:");
do
{
scanf_s("%lf", &radius);
if (!(validate(radius))) {
printf("不能为负数,请重新输入一个整数:");
}
} while (!validate(radius));
area = calcCircle(radius);
break;
case 2:
printf("请输入矩形的长和宽:");
do
{
scanf_s("%lf%lf", &weight, &height);
if (!validate(weight) || !validate(height)) {
printf("不能为负数,请重新输入两个正数:");
}
} while (!validate(weight) || !validate(height));
area = calcSquare(weight, height);
break;
case 3:
printf("请输入三角形的底和高:");
do
{
scanf_s("%lf%lf", &weight, &height);
if (!validate(weight) || !validate(height)) {
printf("不能为负数,请重新输入两个正数:");
}
} while (!validate(weight) || !validate(height));
area = calcTriangle(weight, height);
break;
default:
printf("只能输入1~3整数,请重新输入:");
break;
}
printf("图形面积为:%.2lf\n", area);
}

double calcCircle(double radius)
{
return 3.14 * radius * radius;
}

double calcSquare(double weight, double height)
{
return weight * height;
}

double calcTriangle(double weight, double height)
{
return weight * height / 2;
}

int validate(double num)
{
return num > 0; // 如果 num>0, 返回一个非零值,表示真。
}

C-Language 自定义函数

求次幂函数power

#include <stdio.h>

double power(double, int); // 形式参数

int main()
{
printf("%.2lf的%d次幂等于:%.2lf\n", 5.2, 2, power(5.2, 2)); //实际参数
return 0;
}

double power(double num1, int num2) // 形式参数
{
double result = 1;
int i;
for (i = 0; i < num2; i++)
{
result *= num1; // 累乘
}
return result;
}

我眼中的高级测试工程师

满足什么样的技术和经验才算高级工程师呢?说说我心中的高级工程师。

具有丰富的行业测试经验

最好有传统和互联网大公司工作经验,没有的话至少与这些公司的高级测试工程师有交流,了解他们是如何开展测试的,有助提高自己的眼界。

有良好的测试基础

掌握必要的测试理论,熟悉测试流程,需求分析,测试用例设计方法,根据项目实际需要制定测试方案。

有丰富的业务能力

做好功能测试的前提是熟悉业务,能更好的站在产品的角度去设计测试用例,才能发现基本功能以外的问题,能给产品提出建设性的需求和意见。

熟悉相关的测试工具

软件测试用到的相关工具非常多,了解和使用过这些工具,能更好的结合公司的要求及项目的需求来权衡引入哪些工具,提高工作效率。

  1. 管理工具:比如JIRA,Testlink,Wiki,Confluence
  2. 持续集成:Jenkins,Bamboo,Travis CI等,了解他们之间的区别以及如何实施。
  3. 自动化测试:web和mobile平台之间是如何做自动化才测试的,用到哪些工具。了解Selenium,WebDriver,Appium,Robotium测试框架,以及用哪些语言去开发自动化测试用例,Python?Java?JavaScript?知道如何选择如何实施。
  4. 性能测试:了解Jmeter,LoadRunner这两个主要的性能测试工具,如何开展性能测试。

有良好的代码能力

良好的代码能力可以快速掌握自动化测试,甚至可以开发测试平台。另外,当你跳槽到任何一家公司可以让你快速熟悉Java、Python、Javascript等任何语言编写的自动化测试用例。

语言能力

包括沟通能力和外语能力。沟通是一个测试人员在工作中必不可少的一项基本技能,良好的沟通会让开发人员了解问题所在,接受你的意见,从产品人员那里更好的了解需求。虽然只有在外企的时候才会用到英语,但是随着测试人员也需要学习很多的技术,开源社区的发展,很多第一手资料都是用英文写的,所以学好英文对于扩展和学习新知识有很大帮助。

所以说成为一名优秀的高级测试工程师所要求的能力还是很多的,一起努力吧!💪

Error: Permission denied (publickey)

如果你想在一台电脑上配置 github 和 bitbucket,如何配置多个 SSH git key?
输入以下命令生成 SSH Key,注意在生成过程中最好输入新的名字,比如 id_rsa_github 和 id_rsa_bitbucket

ssh-keygen -t rsa -C "your_email@youremail.com"

然后将生成的 SSH key 文件内容复制到对应网址的个人用户设置中即可。但是明明按照官方教程做的但是在 git clone 的时候还是遇到以下问题:
Error: Permission denied (publickey)
困恼了几天的错误终于解决了。

参看这个文档

由于我用的是macOS Sierra 10.13.3,文档这里写着如果是macOS Sierra 10.12.2 及以后的版本需要在
~/.ssh 目录下创建一个 config 文件
congfig 文件的具体配置如下:

Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_rsa_github

Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_rsa_bitbucket

配置了这个文件之后,再次尝试

git clone git@github.com:shenxianpeng/blog.git

可以 download 代码了,两个 SSH git 都好用了 : )

Jenkinsfile 配置

最近在做有关 DevOps Build 的时候,学习了 Jenkins 的 Pipeline 的功能,不得不提到的就是 Jenkinsfile 这个文件。

以下面是我配置的 Jenkinsfile 文件及简单说明,更多有关 Pipeline 请看官方文档。

pipeline {
agent any

stages {
// Build 阶段
stage('Build') {
steps {
echo 'Building...'
bat 'npm run build webcomponent-sample'
}
}

// 单元测试阶段
stage('Unit Test') {
steps {
echo 'Unit Testing...'
bat 'npm test webcomponent-sample'
}

post {
success {
// 执行成功后生产报告
publishHTML target: [
allowMissing: false,
alwaysLinkToLastBuild: false,
keepAll: true,
reportDir: 'components/webcomponent-sample/coverage/chrome',
reportFiles: 'index.html',
reportName: 'RCov Report'
]
}
}
}

// E2E 测试阶段
stage('E2E Test') {
steps {
bat 'node nightwatch e2e/demo/test.js'
}
}

stage('Release') {
steps {
echo 'Release...'
}
}
}

post {
// 执行成功是触发
success {
mail bcc: 'email@qq.com',
body: "<b>Project: ${env.JOB_NAME} <br>Build Number: ${env.BUILD_NUMBER} <br>Build URL: ${env.BUILD_URL} ", cc: '', charset: 'UTF-8', from: 'jenkins@qq.com', mimeType: 'text/html', replyTo: '', subject: "SUCCESS: Project Name -> ${env.JOB_NAME}", to: "";
}

// 执行失败时触发
failure {
mail bcc: 'email@qq.com',
body: "<b>Project: ${env.JOB_NAME} <br>Build Number: ${env.BUILD_NUMBER} <br>Build URL: ${env.BUILD_URL} ", cc: '', charset: 'UTF-8', from: 'jenkins@qq.com', mimeType: 'text/html', replyTo: '', subject: "FAILURE: Project Name -> ${env.JOB_NAME}", to: "";
}
}
}

DevOps 实践

我想大多数的团队都面临这样的问题:

  1. 发布周期长
  2. 开发和测试时间短
  3. 开发和测试是两个独立的团队
  4. 不稳定的交付质量
  5. 低收益难维护的UI自动化测试脚本
  6. 不合理的测试权重分配

解决方法:

引入 DevOps 和分层自动化

  • 组件化产品
    • 产品开发引入模块化,数据驱动会使得产品更加容易实施 Unit,Server,UI 自动化测试
  • 优化工程师
    • 开发和测试在未来将没有界限,他们都是开发者,都会产品的质量和客户负责
  • 分层自动化
    • 更合理的测试权重分配,更底层的测试收益越高
  • 引入工具
    • 实施DevOps引入必要的工具,Bitbucket, Jenkins, Sonar, Pipelines, Docker, test framework …

Git 命令备忘

有些git命令总是记不住,在我这台 Ubuntu 使用 web 版 OneNote 不方便,那就把他们记到 Blog 里吧,需要的时候翻看一下。

git remote

git remote -v                 # 查看当前位置的远程代码库
git remote remove origin # 取消远程仓库
git remote add orgin git@github.com:shenxianpeng/nightwatch.git # 关联新的仓库

git log

# 得到某一时段提交日志
git log --after='2017-12-04' --before='2017-12-08' --author=xshen --pretty=oneline --abbrev-commit

git tag

git tag -a v1.6.700 -m 'Release v1.6.700'

# 给前面的提交补上 tag
git log --pretty=oneline
git tag -a v1.6.700 -m 'Release v1.6.700' e454ad98862

git push tag
git push origin --tag

设置 npm install 代理

npm config set proxy=http://10.17.201.60:8080       # 设置代理
npm config set proxy null # 取消代理

设置 cnpm

npm install -g cnpm --registry=https://registry.npm.taobao.org
cnpm install [name]
cnpm sync connect
cnpm info connect

Git remove and add remote repository

如果是通过 https 方式来 pull 和 push 代码,每次都要输入烦人的账号和密码
可以通过切成成 ssh 方式:

# 取消远程仓库
git remote remove origin

# 关联远程仓库
git remote add origin git@github.com:shenxianpeng/blog.git