强制Gradle/Maven刷新缓存并重新从Nexus下载依赖jar包

最近需要搭建一个Nexus私服,完全不能连接外网的那种,各种Jar包都是手动拷过来的,碰到需要gradle和maven强制重新下载依赖的问题。

问题

第一次上传某个jar包(比如junit-4.12.jar)到Nexus上,然后调用gradle build可以正确下载到依赖包。但如果手动删掉了本地缓存的jar包(在~/.gradle下),这时从Nexus的下载过程中断,或者Nexus上暂时不存在这个jar包,那么即使Nexus恢复了正常下载,下次执行gradle build时就一直提示不能够找到jar包。

FAILURE: Build failed with an exception.

- What went wrong:
Could not resolve all dependencies for configuration ':testCompile'.
> Could not find junit:junit:4.12.
  Searched in the following locations:
      http://localhost:8081/nexus/content/groups/public/junit/junit/4.12/junit-4.12.pom
      http://localhost:8081/nexus/content/groups/public/junit/junit/4.12/junit-4.12.jar
  Required by:
      org.codehaus.sonar:example-java-maven:1.0-SNAPSHOT

解决方案

回到自己的工作目录下,带参数执行gradle强制刷新~/.gradle下的文件缓存

1
gradle build --refresh-dependencies

Read More

使用Groovy语言替代JUnit为Java程序编写单元测试

(本文改编自 @申导 翻译的《有效的单元测试》,如果对本文感兴趣,请支持正版书籍。)

编程是用计算机可理解的语言来表达你的想法和意图。对于Java程序员来说就是编写一种可以由Java编译器编译为可以运行在JVM上的字节码的代码。不止一种编程语言可以编写能运行在JVM上的代码,不过每种JVM语言都具有其独特的语法和感觉,但有一点是相同的:关于在JVM创建应用程序这件事上,她们都号称比Java更加简洁和更具表达力。

另类JVM语言

另类JVM语言的历史可追溯到15年前,那时Jim Hugunin在编写Jython,即一种JVM上的Python语言实现。尽管Jython难以获得发展的动力,但它启发了后来许多JVM语言的出现。

受到Jython的启发,2003年Groovy语言开始在JVM上登场,有着精简语法的Groovy承诺与Java代码之间流畅的互操作性和极高简洁性,使之成为JVM上编写脚本的重要选择。其他运行在JVM平台上的语言还包括Scala, JRuby, Clojure等,以及Java本身。

概括来说,各种另类JVM语言的一些潜在优势在于:

  • 更少的样板代码语法可以去芜存菁
  • 更多的文本(literal)数据结构
  • 针对标准类型的额外方法
  • 更多强大的语法结构

Read More

函数式Python中的Pipe与itertools

可迭代器(iterable),不仅限于list/str等,还包括任何包含有yield关键字的函数,后者未必有规律的迭代特征。标准库中的itertools包提供了更加灵活的产生迭代器的工具,这些工具的输入大都是已有的迭代器函数的封装,并且itertools给出的函数都是针对广义迭代器而言。而len()等函数是针对狭义迭代器,即sequence(i.e. str, list, tuple)而言的。
以内置函数range()为例,执行结果会是一次性计算好整个序列。这对于很长的序列来说会比较耗时,甚至带来性能问题。因而,python还提供了内置函数,提供了惰性求值版本,那就是xrange()。它利用yield特性,第一次执行时仅仅返回迭代器,不到用时是不会求值的。
实际上,itertools提供的函数都是惰性的,并且给原内置函数都重写了惰性版本。如imap()对于内置的map()

扩展库Pipe则对内置函数和部分itertools进行了封装,提供了类似unix bash下的管道式调用风格,更接近人类从左到右的阅读习惯,使得代码更加优雅。其他动态语言,如ruby, c#-lambda java8-lambda也都提供了类似的链式调用形式。
另外,也提供了@Pipe装饰器,可以非常方便地扩展出自己的管道函数,或者继续封装其他itertools中的有用函数。

这里是Pipe官方给出的例子,用管道函数式编程解出https://projecteuler.net/中的三道题目:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# Find the sum of all the multiples of 3 or 5 below 1000.
euler1 = (itertools.count() | select(lambda x: x * 3) | take_while(lambda x: x < 1000) | add) \
+ (itertools.count() | select(lambda x: x * 5) | take_while(lambda x: x < 1000) | add) \
- (itertools.count() | select(lambda x: x * 15) | take_while(lambda x: x < 1000) | add)
assert euler1 == 233168

# Find the sum of all the even-valued terms in Fibonacci which do not exceed four million.
euler2 = fib() | where(lambda x: x % 2 == 0) | take_while(lambda x: x < 4000000) | add
assert euler2 == 4613732

# Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.
square = lambda x: x * x
euler6 = square(itertools.count(1) | take(100) | add) - (itertools.count(1) | take(100) | select(square) | add)
assert euler6 == 25164150

注意:所有惰性求值的迭代器,都是只能求值一次的,如果再次求值会什么也得不到,因为yield堆栈已经走到底,无法回头。因此,当要对惰性迭代器重复使用时,必须故意地提前将其求值展开,或者利用itertools.tee来克隆一个迭代器。

Read More

Python中多继承与super()用法

Python类分为两种,一种叫经典类,一种叫新式类。两种都支持多继承。

考虑一种情形,B继承于A,C继承于A和B, 但C需要调用父类的__init__()函数时,前者会导致父类A的__init__()函数被调用2次,这是不希望看到的。而且子类要显式地指定父类,不符合DRY原则。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 经典类
class A():
def __init__(self):
print 'A'

class B(A):
def __init__(self):
A.__init__(self)
print 'B'

class C(B, A):
def __init__(self):
A.__init__(self)
B.__init__(self)
print 'C'

采用新式类,要求最顶层的父类一定要继承于object,这样就可以利用super()函数来调用父类的__init__()等函数,每个父类都执行且执行一次,并不会出现重复调用的情况。而且在子类的实现中,不用到处写出所有的父类名字,符合DRY原则。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 新式类
class A(object):
def __init__(self):
print 'A'

class B(A):
def __init__(self):
super(B, self).__init__()
print 'B'

class C(B, A):
def __init__(self):
super(C, self).__init__()
print 'C'

采用super()方式时,会自动找到第一个多继承中的第一个父类,但是如果还想强制调用其他父类的__init__()函数或两个父类的同名函数时,就要用老办法了。

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

class Person(object):
name = ""
sex = ""
def __init__(self, name, sex='U'):
print 'Person'
self.name=name
self.sex=sex


class Consumer(object):
def __init__(self):
print 'Consumer'

class Student(Person, Consumer):
def __init__(self, score,name):
print Student.__bases__
super(Student, self).__init__(name, sex='F')
Consumer.__init__(self)
self.score=score

s1 = Student(90, 'abc')
print s1.name, s1.score, s1.sex


好用的bash提示符和vim配置

定制bash命令行的提示信息,用彩色显示,还包括当前git branch等。
另外还有vi编辑器的配置,让电脑更好用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
##### ~/.bashrc

alias ls="ls -G"
alias ll="ls -alG"

function parse_git_branch_and_add_brackets {
git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(. *\)/\ \1\]/'
}

export PS1="\[\e[32;40m\]\u@ \[\e[33;40m\]\w \[\033[0;34m\]\$(parse_gi t_branch_and_add_brackets) \[\033[0m\]\$ "



##### ~/.vimrc

set nocompatible
set cursorline
colorscheme torte
set number
syntax on

台湾首次CSD认证敏捷技术实践培训课程

最近在台湾长宏的专业协助下,终于有幸将CSD(敏捷技术实践认证课程)首次带到了台湾。虽然受到台风影响,三天并两天,每晚上到10点,加上内容和练习很多,学员其实会很累。然而学员们现场的认真和积极,真的让我大吃一惊,他们都一直在尽最大努力来完成练习,课后很快地分享出他们的收获与心得。

目前Upeform优普丰在中国大陆、台湾及亚洲地区已经形成完整的Scrum认证培训一条龙服务,包括CSM/CSPO/CSD三大核心认证课程,以及申请CSP学分所需的进阶教练课程。同时Uperform也提供到客户现场的咨询与教练服务。
不仅内容品质有口碑保障,而且Uperform在全球Scrum敏捷的中文认证培训市场规模也稳居第一。

Read More

单元测试JUnit入门

(下文摘自 申健/ @申导 翻译的《有效的单元测试》附录A)


在Java生态系统中,现如今事实上的单元测试框架是JUnit。年复一年,越来越少的Java程序员没有见过JUnit测试代码了。不过,每个人总有第一次,某些人也可能使用着其他的测试框架,那么我们编写了这个简短的附录,快速地开始用JUnit来编写测试。

理解JUnit有两个基本元素。首先,你必须了解JUnit测试代码的结构和生命周期。我们从这里开始。我们将看一看如何在测试类(test classes)中定义测试方法(test methods),然后熟悉测试的生命周期——JUnit如何以及何时实例化和调用你的测试类及其方法。

其次,就是JUnit的断言(Assertion) API。基本的和常用的断言方法很简单,你看到它们的方法签名就知道如何使用了。因此,我们只会通过名字来调用这些方法,而聚焦于那些缺乏自我解释的更加“不透明”的断言。

总的来说,JUnit是一个小而简单的框架,我毫不怀疑你会快速地学会运行它。最终你会在某些地方卡住,可以求助于专门的JUnit书籍,比如Manning Publication出版的优秀书籍《JUnit in Action (2nd edition)》就会派上用场。在那之前,我希望本附录包含入门需要的全部内容,帮助你跟上本书的其他内容。

Read More

如何进一步提高敏捷组织的灵活性和顺畅度?

引言

2015.5.28,携程网宕机,消耗了10几个小时才恢复,每小时的损失高达100万美元。作为随时处于变化之中的互联网公司,发生事故总是难免的,但在这次宕机中对突发事件中响应得不够灵活顺畅,就很难被接受了,据说几位高级总监已经被开掉了。

近年来,不论大型还是初创公司,纷纷引入敏捷软件开发的理念,遍地开花。敏捷在不同的组织中以不同的形态出现,Scrum、看板、甚至精益创业等等,无不围绕快速迭代和改进的研发理念展开。强调需求分拆,时间分拆,进度可视化,利用度量进行改进等实践,来提高组织协作的顺畅度,提高灵活性以满足随时变化的业务需要。老板、销售、产品经理、项目经理、过程改进人员、开发测试人员都能听得懂,然后开始导入,不亦乐乎。

一段时间后,爱思考的管理者就会冒出一些疑问,怎么开了很多会没是觉得配合不顺畅?怎么还是感觉进度不快?质量也没见提高?于是乎,很多人就都会给出分析:比如开站会的姿势不对,比如看板不够漂亮,比如度量手段不完善,比如团队缺乏正能量,等等。总之,都还是强调深化过程改革和意识培养。但现状却是仍然觉得组织协作不够顺畅,以至于对市场事件和业务需求变化不能够及时响应,业务总是觉得一点需求变更就会花很久才能完成,最终客户方的满意度提高缓慢。

刚刚买到一本《如来神掌》,就以为自己真的会功夫了?

Read More

从管理1.0到管理3.0的大跃进。管,或者不管,问题都在那里,不增不减。

前言

王宇王大爷发表的《拥抱管理2.0世界之“看板”:强迫团队的微观管理工具》,以及路宁路大丝的评论《看板是强迫团队的微观管理工具吗?》,感觉槽点太多,忍不住也来说几句。

(一)

管理1.0、2.0、3.0根本不是线性的发展,不在一个维度上。我认为它们是事物复杂性增加后的主动应对,从1.0到2.0,是简单系统的不断叠加后,想要保证叠加的规范性、完整性和可复制性。而从2.0到3.0,则是要解决复杂系统如何决策的问题。这3个阶段甚至可以同时共存,就像人与草履虫在地球上共存,就像繁荣的首都北京周边山区至今还有很多孩子喝不到牛奶。

想到一个故事,说是大跃进期间,村公社要求每家都要上交所有的粮食和牲畜,只有主人公家里私藏了一口大白猪没有上交。某一天,公社在主人公家里开会讨论两个议题,一是《让群众每天吃到红烧肉》,二是《实现共产主义》。书记说现在没有猪,咱们直接讨论第二个议题吧。书记告诉大家,将来大家都不用劳动了,劳动都由机器负责,大家也不用吃肉了,吃营养药丸就行。村民表决一致通过,要在1970年实现共产主义。突然大白猪叫了一声,被发现了。公社书记说,暂停第二个议题,今晚都到公社食堂去讨论第一个议题。大白猪必须马上上缴,因为它耽误了共产主义进程!

Read More