Stockeye 持续集成之路 —— NotificationStockQuote 开发实录

关键字 :Jenkins、Gradle、Jacoco、Android Studio、JUnit 和 Robolectri(只适用Android API Level 16、 17、18)

预构

  • 故事点(Agile - Scrum):用户可拉下通知框以查看实时股票信息
  • 界面草图(见下图)
  • 软件设计模式 :观察者模式(Notification 为观察者,数据更新服务为目标,可能有多个不同类型观察者,考虑引进中介者模式以减轻服务管理依赖负担)
  • 类:NotificationStockQuote,接口 -> IObserverNotificationStockQuote,数据结构 -> 二维数组(界面布局采取Listview)

项目概览

项目 build.gradle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.13.2'
classpath 'org.robolectric:robolectric-gradle-plugin:0.13.+'
}
}
allprojects {
repositories {
jcenter()
}
}

app. build.gradle

more >>

持续集成之路 —— Stockeye CalendarStock 库开发实录

关键字 :Jenkins、Gradle、JUnit、Jacoco、jar 包和库、TDD

库项目结构

1
2
3
4
5
6
| build.gradle
| src
| |- main
| |- java/com/msolo/stockeye/calendarstock/UtilCalTime.java
| |- test
| |- java/com/msolo/stockeye/calendarstock/UtilCalTimeTest.java

构建脚本(无 Jacoco)

1
2
3
4
5
6
7
8
9
10
11
apply plugin: 'java'
version = 0.1
repositories {
mavenCentral()
}
dependencies {
testCompile 'junit:junit:4.11'
}
task libJavadocs(type: Javadoc) {
source = sourceSets.main.allJava
}

Jenkins 项目配置(无 JaCoCo)

  • 项目名称:android_stockeye_cal_lib
  • 源码管理:https://github.com/mSoloMoon/android_stockeye_calendar_lib.git
  • 构建触发器:Poll SCM -> *
  • 构建步骤1:Invoke Gradle script -> Switch -> clean build javadoc
  • 构建后操作1:Publish JUnit test result report -> XML -> */build/test-results/.xml
  • 构建后操作2:Publish Javadoc -> build/docs/javadoc/

持续集成(无 JaCoCo)

项目首页
测试结果总结

more >>

学习 Gradle —— Java 下一代构建工具(二)

Gradle 构建生命期
初始化阶段(initialization phase):创建 Project 实例 ->
配置阶段(configuration phase):constructs a model representation of the tasks ->
执行阶段(execution phase)

Gradle 构建脚本精要

Gradle 构建的原理 -> 基于 DDD(domain-driven design)进行建模。

构建模块

  • 模块:项目(the Project interface)
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
// Build script configuration
apply(options: Map<String,?>)
buildscript(config: Closure)
//
// Dependency management
dependencies(config: Closure)
configurations(config: Closure)
getDependencies()
getConfigurations()
//
// Properties
getAnt()
getName()
getDescription()
getGroup()
getPath()
getVersion()
getLogger()
setDescription(description: String)
setVersion(version: Object)
//
// File creation
le(path: Object)
les(paths: Object...)
leTree(baseDir: Object)
//
// Task creation
task(args: Map<String,?>, name: String)
task(args: Map<String,?>, name: String, c: Closure)
task(name: String)
task(name: String, c: Closure)
// 示例
setDescription("myProject")
println "Description of project $name: " + project.description

more >>

学习 Gradle —— Java 下一代构建工具(一)

高效软件工程的核心:自动化
自动化构建类型及其进化史:请求式构建 -> 触发式构建 -> 计划式构建
自动化构建工具要素 :任务(DAG - Directed Acyclic Graph,即一段可工作的构件单元 + 依赖)、依赖管理

Gradle 箴言

  • 让不可行变得可行,让可行变得易行,让易行变得简洁
  • Maven VS Gradle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
1
2
3
4
5
6
7
8
9
10
apply plugin: 'java'
group = 'com.mycompany.app'
archivesBaseName = 'my-app'
version = '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testCompile 'junit:junit:4.11'
}

more >>

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 >>