0%

系统趋于稳定,修改的bug通过git来管理,通过git的提交日志及提交文件变更识别潜在的风险。
工具SourceTree,当然eclipse也可以胜任(体验差一点)
这里写图片描述
要达到识别代码变更需具备基本的代码阅读能力,包括:java、js、jsp、html、css
未完待续

这篇文章的主要目的是记录使用python来编写公司发版系统的想法、过程。

一、构思

主要特征

该系统拥有web界面
代码发布功能:可以在web中实现各个webent单独发布、整体发布
git历史查看功能:查看git提交历史、查看每次提交修改文件。所以需要定时自动更新日志。
两次发布版本差异对比功能

实践能力

一个python的web框架
python调度操作git、maven、执行脚本
python写入和读取数据库
python/git版本对比

二、计划

1、寻找一款python的web框架。定为django。
2、学习并实践该框架
3、设计系统的MVC
4、各个功能编码实现和测试

三、执行

django的安装

安装的方法丰富多彩,很简单。参考github上django/django
或者参考官方网站的安装办法。

阅读全文 »

本人是测试人员,包括我在内,团队中有2名测试,整个研发不含测试大概10名(后台前端)。除了负责测试工作,还兼任负责发布公司测试环境及生产环境的代码。

代码环境及架构

公司所属行业为微信电商,使用java流行的MVC框架(这个我还不是很懂,不知道用了Spring哪些东西),这个了解过,只是并不深入,可以参考我的另一篇入门摘抄的java web基础。言归正传:
后台编程语言:java、UI框架kendo ui
web容器:tomcat
微信端:js、html、vue、css、jsp等
代码管理:git
构建工具:maven
部署操作系统:CentOS7
数据库:MySQL
其他数据库或工具:Redis、Memche、RPC、activemq、阿里云sso
桌面开发工具:eclipse

阅读全文 »

if you had used “apt-get update”….
the new update contains some bugs for nvidia drivers….
To slove:
1.get the nvidia software

1
sudo dpkg -l |grep nvidia
1
2
3
rc  nvidia-304                               304.132-0ubuntu0.16.04.2                      amd64        NVIDIA legacy binary driver - version 304.132
rc nvidia-opencl-icd-304 304.132-0ubuntu0.16.04.2 amd64 NVIDIA OpenCL ICD
rc nvidia-settings 361.42-0ubuntu1 amd64 Tool for configuring the NVIDIA graphics driver
阅读全文 »

前言

受《分布式自动化版本发布系统》启发,决定对我们公司现有的shell脚本发版进行升级。业余时间研究,主要达到以下目的:

前二个做完,可以了解python的一些基本语法数据类型,把更新记录写入到数据库便于日常查看。
第三个,续用当前测试环境发布代码的shell脚本。

python3.5 and mysql5.7

mysql5.7 install

参考:官网安装方法
首先:下载MySQL APT Repository。参考链接的方法,设置MySQL APT Repository。

1
2
3
sudo dpkg -i mysql-apt-config_0.8.0-1_all.deb
sudo apt-get update
sudo apt-get install mysql-server
阅读全文 »

特殊变量

变 量 含义 $0 当前脚本的文件名 $n 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。 $/# 传递给脚本或函数的参数个数。 $/* 传递给脚本或函数的所有参数。 $@ 传递给脚本或函数的所有参数。被双引号(” “)包含时,与 $/* 稍有不同,下面将会讲到。 $? 上个命令的退出状态,或函数的返回值。 $$ 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。

转义字符

转义字符 含义 \ 反斜杠 \a 警报,响铃 \b 退格(删除键) \f 换页(FF),将当前位置移到下页开头 \n 换行 \r 回车 \t 水平制表符(tab键) \v 垂直制表符

阅读全文 »

一开始懂一点SWING界面皮毛,打算使用SWING绘制出了计算器的界面,花了大概2个下班业余时间,一点一点开始摸索,知道SWING界面布局的基本原理。然后开始按照教材中讲解的过程去实现,结果发现界面根本不是那么做出来的。在网上找到了java的源代码,开始研究阅读和抄写编译。墨迹一周有如下收获。
1、JFrame是整个界面的底层,所有行为都给予它;
2、任何界面元素都需要个容器(Jpanel类)放置,每个容器需要定义一个基本的布局设置(Layout类)。布局中可以放置各种容器及元素。
3、元素过多,编程绘制界面效率比手绘要快。
4、任何类都功能单一为原则。编程中极容易按流程把功能给混淆导致设计的冗余。
5、Java的监听有所理解:为界面元素添加监听器,扩展java监听类并实现其方法,该方法将监听器捕获的动作事件作为传入参数,然后取得动作事件后执行方法内的业务处理逻辑。

阅读全文 »

目录

主要经验

游戏描述

参考的是《疯狂Java实战演义》——杨恩雄(文字版)中第一章内容。

Java源代码

GobangGame.java

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
package practise.fiveChess;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class GobangGame {
private int WIN_COUNT = 5;
private int posX, posY;
Chessboard chessboard = new Chessboard();

public int getPosX() {
return posX;
}

public void setPosX(int posX) {
this.posX = posX;
}

public int getPosY() {
return posY;
}

public void setPosY(int posY) {
this.posY = posY;
}

public static void main(String[] args) {
//游戏初始化
boolean isOver = false;
System.out.println("游戏开始!");
GobangGame gobangGame = new GobangGame();
Chessboard chessboard = new Chessboard();
chessboard.initBorad();
chessboard.printBoard();
//执行游戏交互
do {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String inputStr = null;
// 判断输入是否合法
while ((inputStr = br.readLine()) != null && gobangGame.isValid(inputStr) && isOver == false) {
int posX = gobangGame.getPosX();
int posY = gobangGame.getPosY();
String colorDark = Chessman.BLACK.getChessman();
String colorWhite = Chessman.WHITE.getChessman();
// 放棋子,如果失败则重放
if (!chessboard.setBoardByMan(posX, posY, colorDark)
|| !chessboard.setBoardByComputer(colorWhite)) {
continue;
}
// 打印棋盘
chessboard.printBoard();
// 判断是否有赢家
if (gobangGame.isWin(chessboard, posX, posY, colorDark)
|| gobangGame.isWin(chessboard, posX, posY, colorWhite)) {
if (gobangGame.isWin(chessboard, posX, posY, colorDark) == true) {
System.out.println("比赛结束!" + colorDark + "获得胜利");
System.out.println("是否继续游戏?y/n");
// 用户确认是否继续游戏,继续则初始化棋盘,否则退出程序
if (br.readLine().contentEquals("y")) {
chessboard.initBorad();
System.out.println("游戏开始!");
chessboard.printBoard();
continue;
} else {
isOver = true;
break;
}
}
if (gobangGame.isWin(chessboard, posX, posY, colorWhite) == true) {
System.out.println("比赛结束!" + colorWhite + "获得胜利");
System.out.println("是否继续游戏?y/n");
// 用户确认是否继续游戏,继续则初始化棋盘,否则退出程序
if (br.readLine().contentEquals("y")) {
chessboard.initBorad();
System.out.println("游戏开始!");
chessboard.printBoard();
continue;
} else {
isOver = true;
break;
}
}
}
}

} catch (IOException e) {
e.printStackTrace();
}
} while (isOver == false);
System.out.println("Game Over!");
}

// 输入合法性检测
public boolean isValid(String str) {
String[] posStrArr = str.split(",");
try {
posX = Integer.parseInt(posStrArr[0]);
posY = Integer.parseInt(posStrArr[1]);
if (posX > chessboard.BOARD_SIZE || posY > chessboard.BOARD_SIZE || posX < 0 || posY < 0) {
System.out.println("输入不合法,请输入合法的坐标范围:0--" + (chessboard.BOARD_SIZE - 1));
return false;
}
} catch (NumberFormatException e) {
//chessboard.printBoard();
System.out.println("输入不合法,请重新按\"x,y\"的形式输入");
return false;
}
return true;
}
//是否继续游戏方法
public boolean isReplay(String enterStr) {
if (enterStr == "y" || enterStr == "Y") {
return true;
} else {
return false;
}
}

//以下方法基于输入棋子坐标,按不同方向(基于棋子坐标),东西|南北|东北-西南|西北-东南。
//东西
public boolean conetX(Chessboard chessboard, int posX, int posY, String chessColor) {
String[][] board;
board = chessboard.getBord();
int count = 1;
try {
int tmpY = posY - 1;
// 输入点不是起点所在列则判断
// 输入点左侧
while (posY >= tmpY && tmpY > 0) {
if (board[posX][tmpY] != chessColor) {
break;
} else {
count++;
tmpY--;
}
}
// 输入点右侧
tmpY = posY + 1;
while (posY <= tmpY && tmpY < chessboard.BOARD_SIZE) {
if (board[posX][tmpY] != chessColor) {
break;
} else {
count++;
tmpY++;
}
}
if (count >= WIN_COUNT) {
return true;
} else {
return false;
}
} catch (Exception e) {
System.out.println("异常错误:" + e.getMessage());
return false;
}
}

/**
* 南北统计
*/
public boolean conetY(Chessboard chessboard, int posX, int posY, String chessColor) {
String[][] board;
board = chessboard.getBord();
int count = 1;
try {
int tmpX = posX - 1;
// 输入点上方,如果输入的是原点则不计
while (tmpX >= 0) {
if (board[tmpX][posY] != chessColor) {
break;
} else {
count++;
tmpX--;
}
}
// 输入点下方
tmpX = posX + 1;
while (posX < tmpX && tmpX < chessboard.BOARD_SIZE) {
if (board[tmpX][posY] != chessColor) {
break;
} else {
count++;
tmpX++;
}
}
// 累加后是否符合要求
if (count >= WIN_COUNT) {
return true;
} else {
return false;
}
} catch (Exception e) {
System.out.println("异常错误:" + e.getMessage());
return false;
}

}

/**
* 东北\西南斜线方向
*/
public boolean conetEN(Chessboard chessboard, int posX, int posY, String chessColor) {
String[][] board;
board = chessboard.getBord();
int count = 1;

try {
int tmpX1 = posX - 1;
int tmpY1 = posY - 1;

// 西北线
while (tmpX1 < posX && tmpX1 >= 0 && tmpY1 < posY && tmpY1 >= 0) {
if (board[tmpX1][tmpY1] != chessColor) {
break;
} else {
count++;
tmpY1--;
tmpX1--;
}
}
// 东南线
int tmpX2 = posX + 1;
int tmpY2 = posY + 1;
while (tmpX2 > posX && tmpX2 < chessboard.BOARD_SIZE && tmpY2 > posY && tmpY2 < chessboard.BOARD_SIZE) {
if (board[tmpX2][tmpY2] != chessColor) {
break;
} else {
count++;
tmpY2++;
tmpX2++;
}
}
if (count >= WIN_COUNT) {
return true;
} else {
return false;
}

} catch (Exception e) {
System.out.println("异常错误:" + e.getMessage());
return false;
}
}

/**
* 东北西南斜线方向
*/
public boolean conetES(Chessboard chessboard, int posX, int posY, String chessColor) {
String[][] board;
board = chessboard.getBord();
int count = 1;
count = 1;
try {
int tmpX1 = posX - 1;
int tmpY1 = posY + 1;
// 东北线
while (tmpX1 < posX && tmpX1 >= 0 && tmpY1 >= posY && tmpY1 < chessboard.BOARD_SIZE) {
if (board[tmpX1][tmpY1] != chessColor) {
break;
} else {
count++;
tmpY1++;
tmpX1--;
}
}
// 西南线
int tmpX2 = posX + 1;
int tmpY2 = posY - 1;
while (tmpX2 < chessboard.BOARD_SIZE && tmpX2 > posX && tmpY2 < posY && tmpY2 >= 0) {
if (board[tmpX2][tmpY2] != chessColor) {
break;
} else {
count++;
tmpY2--;
tmpX2++;
}
}
if (count >= WIN_COUNT) {
return true;
} else {
return false;
}

} catch (Exception e) {
System.out.println("异常错误:" + e.getMessage());
return false;
}
}

// 判断所输入打棋子是否能够赢得比赛
public boolean isWin(Chessboard chessboard, int posX, int posY, String chessColor) {
boolean isWinx = this.conetX(chessboard, posX, posY, chessColor);
boolean isWiny = this.conetY(chessboard, posX, posY, chessColor);
boolean isWinEN = this.conetEN(chessboard, posX, posY, chessColor);
boolean isWinES = this.conetES(chessboard, posX, posY, chessColor);
if (isWinx || isWiny || isWinEN || isWinES) {
return true;
} else {
return false;
}
}
}
阅读全文 »

参考来源:http://www.xuebuyuan.com/2153333.htm

1.Action/Service/DAO简介:

Action是管理业务(Service)调度和管理跳转的。

Service是管理具体的功能的。

Action只负责管理,而Service负责实施。

DAO只完成增删改查,虽然可以1-n,n-n,1-1关联,模糊、动态、子查询都可以。但是无论多么复杂的查询,dao只是封装增删改查。
至于增删查改如何去实现一个功能,dao是不管的。

总结这三者,通过例子来解释:

Action像是服务员,顾客点什么菜,菜上给几号桌,都是ta的职责;

Service是厨师,action送来的菜单上的菜全是ta做的;

Dao是厨房的小工,和原材料打交道的事情全是ta管。

阅读全文 »

java类的成员变量有俩种:一种是被static关键字修饰的变量,叫类变量或者静态变量;另一种没有static修饰,为实例变量。
在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。
在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。
例如,对于下面的程序,无论创建多少个实例对象,永远都只分配了一个staticVar变量,并且每创建一个实例对象,这个staticVar 就会加1;但是,每创建一个实例对象,就会分配一个instanceVar,即可能分配多个instanceVar,并且每个instanceVar的值都只自加了1次。
类的静态变量在内存中只有一个,java虚拟机在加载类的过程中为静态变量分配内存,静态变量位于方法区,被类的所有实例共享。静态变量可以直接通过类名进行访问,其生命周期取决于类的生命周期。

阅读全文 »