git在跟踪bug中的使用
系统趋于稳定,修改的bug通过git来管理,通过git的提交日志及提交文件变更识别潜在的风险。
工具SourceTree,当然eclipse也可以胜任(体验差一点)
要达到识别代码变更需具备基本的代码阅读能力,包括:java、js、jsp、html、css
未完待续
系统趋于稳定,修改的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、各个功能编码实现和测试
安装的方法丰富多彩,很简单。参考github上django/django
或者参考官方网站的安装办法。
主要参考官网的翻译资料:http://python.usyiyi.cn/translate/django_182/index.html
这里从文章发出到现在(2017/1/8),持续有40多天,期间断断续续的看,断断续续的边学边练习里面的例子。插播了很多其他事情,尤其是一些无聊的手机游戏,双休要跟老婆见面,时间蛮少了,坚持下来确实有点苦难,还好基础看完了。继续加油!下面硬着头皮继续下一个阶段的学习实践。
本人是测试人员,包括我在内,团队中有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
Created with Raphaël 2.1.0 研发编码/修改 发版到测试环境 测试确认 发版到生产环境 yes no
流程中两次发版目前都是执行我手动写的脚本。
Created with Raphaël 2.1.0 发版需求 git pull代码 maven编译构建 发布代码到tomcat 重启tomcat 开始测试
当然git由于有分支管理,发布的代码需要根据实际情况进行切换。这里git的分支管理就不再赘述。
由于手工发版实属重复劳动,后来约定定时测试环境每日定时发版2次,一次是中午12点10分,一次是晚上7点30.使用Linux的crontab。解放后的双手就是生产力。
1 | crontab -e #编辑任务,进入文本编辑窗口,输入以下内容。两个脚本分别是拉取代/构建maven项目和发版代码用 |
PS:此处有坑一个,mvn.sh和updateSites.sh中存在git和mvn这两个非系统自带命令,使用crontab定时运行会缺乏环境变量,导致不能执行。解决办法:在脚本中添加:source /etc/profile。
生产环境的代码严格执行测试环境的代码为基准,所以发布的代码直接从tomcat的webent下面打包,唯一的不同是执行打包的时候会讲配置文件替换为生产。配置文件在代码库中做了统一的管理。
Created with Raphaël 2.1.0 发起发版任务 配置文件check 配置文件替换 代码打包 sftp方式拉取代码包 备份源代码发布代码包 发布代码包 上线回归测试
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 | rc nvidia-304 304.132-0ubuntu0.16.04.2 amd64 NVIDIA legacy binary driver - version 304.132 |
2.remove nvidia all
1 | sudo apt-get remove nvidia-opencl-icd-304 nvidia-304 nvidia-settings |
3.restart your computer
1 | init 6 |
受《分布式自动化版本发布系统》启发,决定对我们公司现有的shell脚本发版进行升级。业余时间研究,主要达到以下目的:
前二个做完,可以了解python的一些基本语法数据类型,把更新记录写入到数据库便于日常查看。
第三个,续用当前测试环境发布代码的shell脚本。
参考:官网安装方法。
首先:下载MySQL APT Repository。参考链接的方法,设置MySQL APT Repository。
1 | sudo dpkg -i mysql-apt-config_0.8.0-1_all.deb |
第一个命令需要选择自己将要安装的mysql版本。
启动mysql
安装mysql workbench。
参考:官方网站
以下操作完成了对git log记录数据库。不足之处在于,没有找到pygit2的方法去追加git 日志,先跳过去了。
大部分代码参考:pygit2官网document
1 | import time,datetime |
更新数据涉及到一个增量更新git的log日志问题,pygit2中没有找到类似的api。所以考虑有时间作为新旧数据判断依据。
这里面的难点(对于小白的我来说),是如何比较时间。开始直接比较:
/#下面 datetimelog 是tuple类型的
dataNewtime= datetimelog
/#commit.author.time是long型自然是无法比较的,发现这个是使用了commit.author.time - dataNewtime,编译器提示发现类型不正确。
正确代码:
1 | import time,datetime |
测试后,新增记录被更新到数据库,当然记录很简单,解决的时候百度了很多次。
在百度中看了数篇关于python调用shell的入门文章。推荐使用Python subprocess模块。
Python subprocess模块学习总结
python调用shell命令易如反掌,现在需要考虑的是如何使python调用的脚本联动起来。
本次实验使用了:
未解决,使用的时候类型不匹配错误。
写这篇文章的时候是希望使用python来自动处理目前公司的发版流程,基于实际考虑,我编写的shell脚本已经足够应付发版工作,再深究下去并不是非常必要,目前发版的不足回头总结再弥补也来得及。那么问题来了,用python去实现的必要性?首先明确一点,我使用python的目的是学习和研究。其次,目前对于web系统的了解程度还不够深入,没有真正的学习过一个web框架。所以还是要做一个发布的系统出来。这个内容留到下一篇文章再继续了。
变 量 含义 $0 当前脚本的文件名 $n 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。 $/# 传递给脚本或函数的参数个数。 $/* 传递给脚本或函数的所有参数。 $@ 传递给脚本或函数的所有参数。被双引号(” “)包含时,与 $/* 稍有不同,下面将会讲到。 $? 上个命令的退出状态,或函数的返回值。 $$ 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。
转义字符 含义 \ 反斜杠 \a 警报,响铃 \b 退格(删除键) \f 换页(FF),将当前位置移到下页开头 \n 换行 \r 回车 \t 水平制表符(tab键) \v 垂直制表符
变量替换可以根据变量的状态(是否为空、是否定义等)来改变它的值。
转义字符 含义 ${var} 变量本来的值 ${var:-word} 如果变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值。 ${var:=word} 如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。 ${var:?message} 如果变量 var 为空或已被删除(unset),那么将消息 message 送到标准错误输出,可以用来检测变量 var 是否可以被正常赋值。若此替换出现在Shell脚本中,那么脚本将停止运行。 ${var:+word} 如果变量 var 被定义,那么返回 word,但不改变 var 的值。
在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……
参数处理 说明 $/# 传递到脚本的参数个数 $/* 以一个单字符串显示所有向脚本传递的参数。如”$/*”用「”」括起来的情况、以”1、$2…n”的形式输出所有参数。跟0,表示执行脚本自己的名称。 $$ 脚本运行的当前进程ID号 $! 后台运行的最后一个进程的ID号 $@ 与∗相同,但是使用时加引号,并在引号中返回每个参数。如”@”用「”」括起来的情况、以”1”“2” … “$n” 的形式输出所有参数。 $- 显示Shell使用的当前选项,与set命令功能相同。 $? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
$/* 与 $@ 区别:
相同点:都是引用所有参数。
不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 ” /* ” 等价于 “1 2 3”(传递了一个参数),而 “@” 等价于 “1” “2” “3”(传递了三个参数)。
数组中可以存放多个值。Bash Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小。与大部分编程语言类似,数组元素的下标由0开始。
文件测试运算符用于检测 Unix 文件的各种属性。
属性检测描述如下:
操作符 说明 举例 -d file 检测文件是否是目录,如果是,则返回 true。 [ -d $file ] 返回 false。 -f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 [ -f $file ] 返回 true。 -k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 [ -k $file ] 返回 false。 -p file 检测文件是否是有名管道,如果是,则返回 true。 [ -p $file ] 返回 false。 -u file 检测文件是否设置了 SUID 位,如果是,则返回 true。 [ -u $file ] 返回 false。 -g file 检测文件是否设置了 SGID 位,如果是,则返回 true。 [ -g $file ] 返回 false。 -r file 检测文件是否可读,如果是,则返回 true。 [ -r $file ] 返回 true。 -w file 检测文件是否可写,如果是,则返回 true。 [ -w $file ] 返回 true。 -x file 检测文件是否可执行,如果是,则返回 true。 [ -x $file ] 返回 true。 -s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true。 -e file 检测文件(包括目录)是否存在,如果是,则返回 true。 [ -e $file ] 返回 true。
PS:SUID 是 Set User ID, SGID 是 Set Group ID的意思。设置了suid的程序文件,在用户执行该程序时,用户的权限是该程序文件属主的权限。例如程序文件的属主是root,那么执行该程序的用户就将暂时获得root账户的权限。sgid与suid类似,只是执行程序时获得的是文件属组的权限。
一开始懂一点SWING界面皮毛,打算使用SWING绘制出了计算器的界面,花了大概2个下班业余时间,一点一点开始摸索,知道SWING界面布局的基本原理。然后开始按照教材中讲解的过程去实现,结果发现界面根本不是那么做出来的。在网上找到了java的源代码,开始研究阅读和抄写编译。墨迹一周有如下收获。
1、JFrame是整个界面的底层,所有行为都给予它;
2、任何界面元素都需要个容器(Jpanel类)放置,每个容器需要定义一个基本的布局设置(Layout类)。布局中可以放置各种容器及元素。
3、元素过多,编程绘制界面效率比手绘要快。
4、任何类都功能单一为原则。编程中极容易按流程把功能给混淆导致设计的冗余。
5、Java的监听有所理解:为界面元素添加监听器,扩展java监听类并实现其方法,该方法将监听器捕获的动作事件作为传入参数,然后取得动作事件后执行方法内的业务处理逻辑。
参考:http://blog.csdn.net/frank_softworks/article/details/1629615
源代码:
1 | package myPractise.Creasy2; |
参考的是《疯狂Java实战演义》——杨恩雄(文字版)中第一章内容。
1 | package practise.fiveChess; |
1 | public enum Chessman { |
1 | package practise.fiveChess; |
参考来源: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管。
相互关系是,小工(dao)的工作是要满足厨师(service)的要求,厨师要满足服务员(action)转达的客户(页面用户)的要求,服务员自然就是为客户服务喽。
现在最基本的分层方式,结合了SSH架构。Model层就是对应的数据库表的实体类。Dao层是使用了hibernate连接数据库、操作数据库(增删改查)。
Service层:引用对应的Dao数据库操作。Action层:引用对应的Service层,在这里结合Struts的配置文件,跳转到指定的页面,当然也能接受页面传递的请求数据,也可以做些计算处理。
以上的Hibernate,Struts,都需要注入到spring的配置文件中,Spring把这些联系起来,成为一个整体。
2.三大框架Struts/Hibernate/Spring
简单地说:
Struts——控制用的;
Hibernate——操作数据库的;
Spring——解耦用的。
java类的成员变量有俩种:一种是被static关键字修饰的变量,叫类变量或者静态变量;另一种没有static修饰,为实例变量。
在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。
在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。
例如,对于下面的程序,无论创建多少个实例对象,永远都只分配了一个staticVar变量,并且每创建一个实例对象,这个staticVar 就会加1;但是,每创建一个实例对象,就会分配一个instanceVar,即可能分配多个instanceVar,并且每个instanceVar的值都只自加了1次。
类的静态变量在内存中只有一个,java虚拟机在加载类的过程中为静态变量分配内存,静态变量位于方法区,被类的所有实例共享。静态变量可以直接通过类名进行访问,其生命周期取决于类的生命周期。
而实例变量取决于类的实例。每创建一个实例,java虚拟机就会为实例变量分配一次内存,实例变量位于堆区中,其生命周期取决于实例的生命周期。
结果为:
1
0 (成员变量具有缺省值 而局部变量则没有)
把代码改为:
结果则为
0
1
0