遇见 JenKins - 持续集成(一)

一个程序员(工程师)的工作要是少了持续集成这一环节,他(她)就不能算是程序员。

JenKins 认知

持续开发 -> 持续测试 -> 持续构建 -> 持续部署/交付

JenKins 是什么

  • 持续性构建或测试软件工程
  • 监控外部工作的执行

JenKins 最佳实践

  • 安全性:强制采取认证和权限控制
  • 周期性备份
  • 使用“文件指纹”(file fingerprinting)管理(因交叉工程协作带来的)依赖性
  • 最可靠的构建是清洁构建(clean builds,which are built fully from Source Code Control)
  • 紧密结合问题追踪系统(如 JIRA 或 bugzilla)以减少手工维护变更记录的麻烦
  • 紧密结合源代码浏览工具(如 FishEye),但前提是使用 Subversion 作为源代码版本管理工具
  • 坚持对每一个构建生成趋势报告和进行自动化测试
  • 为 JenKins 分配足够多的磁盘空间
  • 为要移除的构建工作打包仓储
  • 为不同的分支(维护或开发)都单独建立构建工作
  • 为平行构建的工作分配不同的端口,但最好避免同时构建多个工程
  • 使用 Email 功能以保持团队对开发工作的感知
  • 分步式测试计划以保证失败地构建得以尽早上报(比如在整体套件测试之前进行嗅探性测试)
  • 为构建工作制定维护计划,比如定期清理以避免磁盘耗尽
  • 为成功的构建上标签,描述
  • Configure Jenkins bootstrapper to update your working copy prior to running the build goal/target
  • In larger systems, don’t build on the master(do this by setting the executor count to zero)

more >>

Udacity公开课:软件调试(优酷旁听)

Udacity公开课:CS259软件调试

课程概览

目标
如何系统化的调试
使用自动化调试工具
使用一系列试验,进行程序科学调试假设验证

大纲

  1. 调试如何工作?
  2. 断言实验
  3. delta 自动化调试方法
  4. 程序 bug 如何产生
  5. 重复错误如何发生,统计调试错误源
  6. 信息挖掘 :bug 数据库和变更数据库

第一节

序言:深夜调试

  • 程序员手工调试的弊端:注意力有限,不集中;花费更多时间以致减少了和陪伴家人的时间;
  • 软件工作量占比:测试和调试经常在 50% ~ 75%
  • 调试的困难:无法估计

启程

  • 处理 HTML 输出文本(tag 模式与有限状态机);
  • 简单例子foo:两种状态(tag、text);
  • 第一个漏洞,foo:三种状态(tag、text 和 quote)
  • 第二个漏洞,”foo“;
  • 任意输出变量值调试:时间杀手!任意变更代码调试:混乱杀手!
  • 《代码大全》- 历史:魔鬼调试指南;
  • 修复调试;糊弄单元调试案例;
  • 程序变量的状态 -> defect 感染点 -> 感染点传染 -> 错误;引发感染的情形 -> 调试/测试的 cases
  • 解决:科学假设 -> 预测 -> 试验 -> 渐进式改进假设 —> 理论
  • 假设I:简单测试,输入”foo” -> “bar” -> “”;(因果链)

进度:Udacity公开课:CS259软件调试:01-29 你好断言

未完待续

Java 面试题 - Stack and Queue

ArrayDeque

  • Resizable-array implementation of the Deque interface.
  • 此类很可能在用作堆栈时快于 Stack,在用作队列时快于 LinkedList。大多数 ArrayDeque 操作以摊销的固定时间运行。

JAVA中Stack和Heap的区别

  • 每个应用程序运行时,都有属于自己的一段内存空间,用于存放临时变量、参数传递、函数调用时的PC值的保存。这叫stack。
  • 所有的应用可以从一个系统共用的空间中申请供自己使用的内存,这个共用的空间叫heap。
  • Java中对象都是分配在heap(堆)中。从heap中分配内存所消耗的时间远远大于从stack产生存储空间所需的时间。
  • 要使用heap中申请的变量或对象只能定义变量指针,并要求在运行过程中通过new来动态分配内存空间,而且必须显示地free你申请过的内存,不过Java的垃圾回收机解决了这个问题,它会帮你释放这部分内存。
  • 另外,栈有一个很重要的特殊性,就是存在栈中的数据可以共享。int a=3; int b=3; 创建 a 变量后,由于在栈中已经有3这个字面值,于是 b 直接指向3的地址。在编译器内部,遇到 a=4;时,它就会重新搜索栈中是否有4的字面值,如果没有,重新开辟地址存放4的值;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。
  • 像String str = “abc”;这种场合下,其字符串值是保存了一个指向存在栈中数据的引用;

面试题补充

1、 Describe how you could use a single array to implement three stacks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int stackSize = 300;
int[] buffer = new int [stackSize * 3];
int[] stackPointer = {0, 0, 0}; // stack pointers to track top elem
void push(int stackNum, int value) {
/* Find the index of the top element in the array + 1, and
* increment the stack pointer */
int index = stackNum * stackSize + stackPointer[stackNum] + 1;
stackPointer[stackNum]++;
buffer[index] = value;
}
int pop(int stackNum) {
int index = stackNum * stackSize + stackPointer[stackNum];
stackPointer[stackNum]--;
int value = buffer[index];
buffer[index]=0;
return value;
}
int peek(int stackNum) {
int index = stackNum * stackSize + stackPointer[stackNum];
return buffer[index];
}
boolean isEmpty(int stackNum) {
return stackPointer[stackNum] == stackNum*stackSize;
}

more >>

Java 面试题 - Arrays and Strings

Java容器类库图


HashMap和Hashtable

  • HashMap不是线程安全的,由于非线程安全,效率上可能高于Hashtable;
  • Hastmap是Java 1.2引进的Map interface的一个实现;其中键和值都是对象,可以包含重复值。HashMap允许null key和null value,而hashtable不允许;
  • 为一个HashMap提供外同步。其中一个方法就是利用Collections类的静态的synchronizedMap(),它创建一个线程安全的Map对象,并返回一个封装的对象。这个对象的方法可以让你同步访问潜在的HashMap;
  • HashMap去掉了HashTable的contains方法,但加上了containsValue()和containsKey()方法;
  • HashTable是线程安全的一个Collection,继承自陈旧的Dictionary类;

more >>

程序员日志 - 2014-10-31

就在昨天升级完Archlinux后,今天中午再次打开时,发现虚拟机无法连接外网;经过以下步骤:验证,排错,改正后,问题得以解决:

1
2
3
4
5
$ systemctl status network.service # 验证:找不到网卡ens33;
$ lspci -k # 排错:确认网卡存在,其名称竟变为eno16777736(为何名称变化了?)
$ vim /etc/systemd/system/network-wireless@.service # 改正:修正网卡名称
$ systemctl reload
$ systemctl restart network.service

午后,浏览:

http://www.v2ex.com
http://www.oschina.net/
https://code.google.com/p/guava-libraries/wiki/GuavaExplained # 初步了解:google guava