1. 需要有全职的有威信,有能力的产品负责人(PO-Product Owner).
2. PO要和Scrum Team、其他的利益相关者(stakeholder)一起工作
3. 有PO来创建和管理产品backlog.
4. Scrum每日站会必须的3个问题(完成了什么,准备做什么,有什么障碍)。
5. Scrum每日站会要在固定的地方时间不要超过15分钟。
6. 有规律的Sprint长度(不超过30天)
7. 在Sprint计划会议上创建Sprint Backlog和经过详细估算的任务列表。
8. 一定要有Sprint的燃尽图。
9. Team必须的设备及相关的供应要齐全。
10. 使用回顾会议确保过程在不断提升。
11. 有明确的对于“任务完成”的定义。
12. 按照合理的速率给出承诺(根据Sprint的工作量估计)。
13. 团队大小在7 +/- 2,最多不能超过12人
14. 跨职能的团队包括Scrum Master和PO.
15. 自组织的团队 - 团队成员志愿挑选任务。
16. Scrum master要跟踪进度,并且为团队扫清障碍。
17. 确保Team不被外界干扰。
18. Sprint之间不能间断。
19. 合理的节奏 - 根据固定时间段来确定任务量, 不只是一个进度表。
20. 质量是第一,不需要在质量上讨价还价 - 代码缺陷永远位于Backlog的最上层。
javaeye上一篇文章不错,介绍
Linux文件系统简介的,讲解比较基础,遗忘的时候看下不错的,记录一下~!~
http://www.javaeye.com/topic/816268
转载于:http://www.infoq.com/cn/articles/skills-for-scrum-agile-teams
敏捷项目的工程独特性
1.
设置开发环境
在传统项目中,团队可以投入充分的时间来设置开发环境;而在敏捷团队里面,他们需要从第一刻时间起就能产出。根据我们的经验,我们认识到缺乏设置开发环境的相关文档是设置环境如此耗时的一个关键原因。第二个关键原因是在设置过程中涉及的手工步骤数。在第0次sprint,我们必须记录每一件开发人员必须做了才能开始编写代码,并集成团队其他人工作的小事。
2.
自动构建
让我们尽早失败!我们领悟到,手工构建可能既脆弱,又特定于某一台机器,而且当时间耗费在手工构建的基础工作上面时,开发和测试的时间就被挤占掉了。除去最小的项目,自动构建过程对于每一个项目都是必不可少的。我们认识到,即使需要抽出时间来创建自动构建的环境,你以后是能把这些时间赚回来的。这也使得我们更易于确保项目有一个人人共有的标准化构建。
3.
持续集成
根据我们过去的经验,我们领悟到,等到最后的几个星期才去把不同团队成员的代码集成到一起是一个灾难。如果你已经拥有了自动构建,接下来的事情就是持续集成。当然,版本控制(或者软件配置管理——另一个更为正式的和令人印象深刻的名字)是自动构建和持续集成环境的前提。我们学到的一个重要教训是,你越快识别出集成的错误,你就能越快地解决这些问题。我们曾经使用过的主要工具包括
CruiseControl、
CruiseControl.Net和
Bamboo。 hadson,基础集成还是不错的。
4.
单元测试
在高度流动的环境中,随着多个开发人员一起工作、需求的变更和优先级的不断变化,确保昨天可以运行的东西今天也能运行,这是至关重要的。此外,我们还要与集成出现的错误为战。一种方法(我们从艰难岁月中学习得来)是使用单元测试,这样代码的更改不会破坏现有的功能。我们也开始在开发编码之前编写单元测试用例。我们曾经使用过的主要工具包括
JUnit(以及其他的xUnit工具如
NUnit、
HttpUnit等)和
MockObjects。
5.
重构
在传统的项目中,通常有一个人保护他们的代码库,直到代码集成阶段。但是在敏捷里面,我们持代码集体所有制的观点——所有的代码属于所有的开发人员,只要开发人员认为有必要,每个人都能不受约束地去改善代码。在一段时间里面,我们的代码库开始出现奇怪的行为——解决办法就是重构(感谢Martin
Fowler在他的同名著作中把重构一词推广开来)。重构的本质归结为修改代码以改善代码的结构和清晰度,但不改变代码的功能。我们学到的一个重要教训是在重构代码之前使用单元测试作为安全网,我们曾经使用过的一些主要工具包括Eclipse、NetBeans、IntelliJ IDEA的和Visual
Studio.NET。
在敏捷团队之中工作所必备的行为特征
由于敏捷团队不同于普通的团队,并且非常倚赖于有效果和有效率的沟通和快速执行,敏捷团队更需要使用软技能。如果我们意识到这一点,并积极鼓励使用这些特征和技能,我们可以使得敏捷团队更有价值和富有成效。
自组织往往倚赖于诸如正反馈、负反馈、深度探索和广度调研之间取得平衡以及多重互动的基本要素。根据我们的经验,团队可能由于许多文化和社会因素无法给予正确的反馈或者回避人与人之间的互动。
根据我个人的经验,这仍然是一个“神话”。我们总是倾向于患有“可预测性综合症”——如果我们做更多的规划,我们将更加功能预测。
团队需要有良好的纪律、有能力承担责任、尽忠尽责以及承担职责和所有权。
团队需要拥有的关键技能之一是有能力寻求帮助,并寻求他人的评价。在某些情形下,我们已经看到了“自我”因素表现为一个主要的障碍。
有些时候,承担责任,尽忠尽责和协作精神是理所当然的,但是根据以往的经验,为了这些能够出现,我们有时需要外部干预。
有些我们常常倾向于忽视的关键技能是积极主动、在激烈的环境中享受工作和易于适应新的形势和框架。
我们的大多数项目都是分布式的,这意味着在客户和服务供应商之间将会共同使用Scrum。在这种情况下,诸如管理多样化团队、时间管理、外交技巧和领导力等技能是非常关键的。
敏捷团队的成功“咒语”
对于任何一个希望成功和高效的敏捷项目,团队需要对向同侪学习(不管资历和专业知识)表现出更大的热情和正确的态度。必须保证一个无畏表达的安全网,这样才会展现出真正的友情,而这反过来会增强团队成员对团队目标的关注,而不是“哪些由我来做”?
结论
根据我个人的经验和观察,对于提高生产率所需的技能,敏捷项目与传统项目有所不同。本文定义了团队提高生产率所需的行为和技术技能。具有这些“delta”
特征的人应该具备了合适的行为和技术技能,这些技能使得他们在敏捷项目中的工作能够富有成效。对于这些技能的总结请见下表。
技能表
角色
|
技术技能(在不同的方面)
|
行为技能
|
开发人员
|
CRUD操作,开发框架不同层之间的调用
单元测试(工具——NUnit、JUnit)
代码覆盖率的概念和工具
代码审查的概念和工具
持续集成工具
重构的概念
代码味道的概念
Scrum过程
|
沟通
合作
时间管理/计划
思维
冲突管理
处理更改/灵活性
决策
团队合作/团队建设
处理压力
问题解决
领导
外交
|
QA
|
“完成”的定义 —> 验收标准
测试管理
自动化/脚本
环境设置
数据库概念
|
与开发人员相同
|
Scrum Master
|
Scrum过程
模板和使用
项目管理工具
持续集成工具
设置开发环境
|
开发人员的技能+推动力
|
作者简介
Prasad,拥有10年的IT服务行业经验,他第一次接触敏捷项目是在2005年微软的一个项目;从那时起,他为许多公司如GE、思科、可口可乐等,针对敏捷及其变体提供了解决方案开发、培训、咨询以及指导。目前他正在Symphony
Services的敏捷实验室担任经理。Symphony40%的项目都是关于敏捷或其不同的形式,并且自2004年起就通过敏捷为客户提供商务的关键价值。你可以通过pprabhak@symphonsysv.com与他联系。
查看英文原文:Skills for
Scrum Agile Teams
敏捷最大的特点是:不但快,反应要更快。
最终的目的是:提升效率。
敏捷是一种思想:
沟通:个体交互
简单:快速交付
反馈:客户合作
勇气:响应变化
关键条件还是目标一直的团队
共同愿景
高效沟通
互相信任
严格执行
迅速迭代,越变越美,允许试错
敏捷精华: 小胜+ 反思
想法是:
1.现在列出你认为你能完成的一件事。
比如我认为每天30分钟的话,下一周我能读一本书:书名叫《人人都是产品经理》
2.每天把进度记录到地下
我会把读完的页数写出来,加上一点点感想
看完后,总结下。
任何一个有经验的程序员都知道,软件开发遵循着一些不成文的法则。然而,如果你不遵循这些法则也并不意味着会受到惩罚;相反,有时你还会获得意外的好处。下面的就是软件编程中的21条法则:
- 任何程序一旦部署即显陈旧。
- 修改需求规范来适应程序比反过来做更容易。
- 一个程序如果很有用,那它注定要被改掉。
- 一个程序如果没用,那它一定会有很好的文档。
- 任何程序里都仅仅只有10%的代码会被执行到。
- 软件会一直膨胀到耗尽所有资源为止。
- 任何一个有点价值的程序里都会有至少一个bug。
- 原型完美的程度跟审视的人数成反比,反比值会随着涉及的资金数增大。
- 软件直到被变成产品运行至少6个月后,它最严重的问题才会被发现。
- 无法检测到的错误的形式无限多样,而能被检测到的正好相反,被定义了的十分有限。
- 修复一个错误所需要投入的努力会随着时间成指数级增加。
- 软件的复杂度会一直增加,直到超出维护这个程序的人的承受能力。
- 任何自己的程序,几个月不看,形同其他人写的。
- 任何一个小程序里面都有一个巨大的程序蠢蠢欲出。
- 编码开始的越早,花费的时间越长。
- 一个粗心的项目计划会让你多花3倍的时间去完成;一个细心的项目计划只会让你多花2倍的时间。
- 往大型项目里添加人手会使项目更延迟。
- 一个程序至少会完成90%,但永远完成不了超过95%。
- 如果你想麻烦被自动处理掉,你得到的是自动产生的麻烦。
- 开发一个傻瓜都会使用的软件,只有傻瓜愿意使用它。
- 用户不会真正的知道要在软件里做些什么,除非使用过。
[英文出处]:
21 Laws of Computer Programming
public class CheckQueryParams {
private static interface Validation{
void check(QueryInfo query);
}
private static List<Validation> validations = new ArrayList<Validation>();
static {
validations.add(new Validation() {
public void check(QueryInfo query) {
if(StringUtils.isEmpty(query.getStartKey()) && StringUtils.isEmpty(query.getEndKey()))
throw new RuntimeException("Both keys can not be null or empty at the same time");
}});
}
public static void check(QueryInfo query) {
for(Validation validation : validations) {
validation.check(query);
}
}
}
public class LRUCache<K,V> {
final private int capacity;
final private Map<K,Reference<V>> map;
final private ReentrantLock lock = new ReentrantLock();
final private ReferenceQueue<Reference<V>> queue = new ReferenceQueue<Reference<V>>();
public LRUCache(int capacity) {
this.capacity = capacity;
map = new LinkedHashMap<K,Reference<V>>(capacity,1f,true){
@Override
protected boolean removeEldestEntry(Map.Entry<K,Reference<V>> eldest) {
return this.size() > LRUCache.this.capacity;
}
};
}
public V put(K key,V value) {
lock.lock();
try {
map.put(key, new SoftReference(value,queue));
return value;
}finally {
lock.unlock();
}
}
public V get(K key) {
lock.lock();
try {
queue.poll();
return map.get(key).get();
}finally {
lock.unlock();
}
}
public void remove(K key) {
lock.lock();
try {
map.remove(key);
}finally {
lock.unlock();
}
}
}
1.同步对象的恒定性
对于局部变量和参数来说,java里面的int, float, double, boolean等基本数据类型,都在栈上。这些基本类型是无法同步的;java里面的对象(根对象是Object),全都在堆里,指向对象的reference在栈上。
java中的同步对象,实际上是对于reference所指的“对象地址”进行同步。
需要注意的问题是,千万不要对同步对象重新赋值。举个例子。
class A implements Runnable{
Object lock = new Object();
void run(){
for(...){
synchronized(lock){
// do something
...
lock = new Object();
}
}
}
}
run函数里面的这段同步代码实际上是毫无意义的。因为每一次lock都给重新分配了新的对象的reference,每个线程都在新的reference同步。大家可能觉得奇怪,怎么会举这么一个例子。因为我见过这样的代码,同步对象在其它的函数里被重新赋了新值。这种问题很难查出来。所以,一般应该把同步对象声明为final。 final Object lock = new Object();
使用Singleton Pattern 设计模式来获取同步对象,也是一种很好的选择。
2.如何放置共享数据,粒度,跨类的同步对象
实现线程,有两种方法,一种是继承Thread类,一种是实现Runnable接口。
首先,把需要共享的数据放在一个实现Runnable接口的类里面,然后,把这个类的实例传给多个Thread的构造方法。这样,新创建的多个Thread,都共同拥有一个Runnable实例,共享同一份数据。如果采用继承Thread类的方法,就只好使用static静态成员了。如果共享的数据比较多,就需要大量的static静态成员,令程序数据结构混乱,难以扩展。这种情况应该尽量避免。编写一段多线程代码,处理一个稍微复杂点的问题。两种方法的优劣,一试便知。
线程同步的粒度越小越好,即,线程同步的代码块越小越好。尽量避免用synchronized修饰符来声明方法。尽量使用synchronized(anObject)的方式,如果不想引入新的同步对象,使用synchronized(this)的方式。而且,synchronized代码块越小越好。
对于简单的问题,可以把访问共享资源的同步代码都放在一个类里面。
但是对于复杂的问题,我们需要把问题分为几个部分来处理,需要几个不同的类来处理问题。这时,就需要在不同的类中,共享同步对象。比如,在生产者和消费者之间共享同步对象,在读者和写者之间共享同步对象。
如何在不同的类中,共享同步对象。有几种方法实现,
(1)前面讲过的方法,使用static静态成员,(或者使用Singleton Pattern.)
(2)用参数传递的方法,把同步对象传递给不同的类。
(3)利用字符串常量的“原子性”。
对于第三种方法,这里做一下解释。一般来说,程序代码中的字符串常量经过编译之后,都具有唯一性,即,内存中不会存在两份相同的字符串常量。
(通常情况下,C++,C语言程序编译之后,也具有同样的特性。)
比如,我们有如下代码。
String A = “atom”;
String B = “atom”;
我们有理由认为,A和B指向同一个字符串常量。即,A==B。注意,声明字符串变量的代码,不符合上面的规则。
String C= new String(“atom”);
String D = new String(“atom”);
这里的C和D的声明是字符串变量的声明,所以,C != D。
有了上述的认识,我们就可以使用字符串常量作为同步对象。比如我们在不同的类中,使用synchronized(“myLock”), “myLock”.wait(),“myLock”.notify(), 这样的代码,就能够实现不同类之间的线程同步。本文并不强烈推荐这种用法,只是说明,有这样一种方法存在。本文推荐第二种方法,(2)用参数传递的方法,把同步对象传递给不同的类。
3.线程之间的通知
这里使用“通知”这个词,而不用“通信”这个词,是为了避免词义的扩大化。
线程之间的通知,通过Object对象的wait()和notify() 或notifyAll() 方法实现。
下面用一个例子,来说明其工作原理:
假设有两个线程,A和B。共同拥有一个同步对象,lock。
1.首先,线程A通过synchronized(lock) 获得lock同步对象,然后调用lock.wait()函数,放弃lock同步对象,线程A停止运行,进入等待队列。
2.线程B通过synchronized(lock) 获得线程A放弃的lock同步对象,做完一定的处理,然后调用 lock.notify() 或者lock.notifyAll() 通知等待队列里面的线程A。
3.线程A从等待队列里面出来,进入ready队列,等待调度。
4.线程B继续处理,出了synchronized(lock)块之后,放弃lock同步对象。
5.线程A获得lock同步对象,继续运行。
例子代码如下:
public class SharedResource implements Runnable{
Object lock = new Object();
public void run(){
// 获取当前线程的名称。
String threadName = Thread.currentThread().getName();
if( “A”.equals(threadName)){
synchronized(lock){ //线程A通过synchronized(lock) 获得lock同步对象
try{
System.out.println(“ A gives up lock.”);
lock.wait(); // 调用lock.wait()函数,放弃lock同步对象,
// 线程A停止运行,进入等待队列。
}catch(InterruptedException e){
}
// 线程A重新获得lock同步对象之后,继续运行。
System.out.println(“ A got lock again and continue to run.”);
} // end of synchronized(lock)
}
if( “B”.equals(threadName)){
synchronized(lock){//线程B通过synchronized(lock) 获得线程A放弃的lock同步对象
System.out.println(“B got lock.”);
lock.notify(); //通知等待队列里面的线程A,进入ready队列,等待调度。
//线程B继续处理,出了synchronized(lock)块之后,放弃lock同步对象。
System.out.println(“B gives up lock.”);
} // end of synchronized(lock)
boolean hasLock = Thread.holdsLock(lock); // 检查B是否拥有lock同步对象。
System.out.println(“B has lock ? -- ” +hasLock); // false.
}
}
}
public class TestMain{
public static void main(){
Runnable resource = new SharedResource();
Thread A = new Thread(resource,”A”);
A.start();
// 强迫主线程停止运行,以便线程A开始运行。
try {
Thread.sleep(500);
}catch(InterruptedException e){
}
Thread B = new Thread(resource,”B”);
B.start();
}
}
原文地址:
http://coolszy.javaeye.com/blog/588627 作者:
coolszy
1,朋友请你吃饭,不要觉得理所当然,请礼尚往来,否则你的名声会越来越臭。
2,给自己定目标,一年,两年,五年,也许你出生不如别人好,通过努力,往往可以改变70(百分号)的命运。破罐子破摔只能和懦弱做朋友。
3,这是个现实的社会,感情不能当饭吃,贫穷夫妻百事哀。不要相信电影,那只是个供许多陌生人喧嚣情感的场所。
4,好朋友里面,一定要培养出一个知己,不要以为你有多么八面玲珑,到处是朋友,最后真心对你的,只有一个,相信我。
5,不要相信星座命理,那是哄小朋友的,命运在自己手中。难道你想等出栋房子或是车子?
6,不喜欢的人少接触,但别在背后说坏话,说是非之人,必定是是非之人,谨记,祸从口出。
7,少玩游戏,这不是韩国,你打不出房子车子还有女人。
8,学好英语,那些说学英语没用的暂时可以不去管,他们要么年纪大了,要么就是自己早过了CET6准备托福了,在这里哗众取宠。你可以不拿证,但一定要学好。
9,知道自己要干什么,夜深人静,问问自己,将来的打算,并朝着那个方向去实现。
10,偶尔翻翻时尚类的杂志,提高一下自己的品位。
11,尽量少看OOXX,正常的男人即使是单身,也不会成天迷恋OOXX。而每次你SY后都会有大量锌元素流失,此元素与你大脑活动有密切联系。
12,每天早上一杯水,预防胆结石。睡前一小时不要喝水,否则会过早出现眼袋。
13,空闲时间不要全拿去泡BAR,读点文学作品,学习一些经营流程,管理规范,国际时事,法律常识。这能保证你在任何场合都有谈资。
14,大家都年轻,没什么钱,不用太在意谁谁又穿AD ,NIKE ,或者其他。而GF对于PRADA,兰蔻,CD,LV,的热恋,你也不必放在心上,女人天生和美挂上了勾,她们只是宁愿相信你能够为她们买一样昂贵的礼物,以满足她们的虚荣心,然后在同伴面前炫耀一番。实则她们也是热爱生活的,而当你有能力完成时,也会觉得把她包装得漂漂亮亮的很是欣慰。
15,要做一件事,成功之前,没必要告诉其他人。
16,头发,指甲,胡子,打理好。社会是个排斥性的接受体,这个星球所需要的艺术家极其有限,请不要冒这个险,就算你留长头发比较好看,也要尽量给人干净的感觉。
17,不要以为你是个男人,就不需要保养。至少饮食方面不能太随便,多吃番茄,海产品,韭菜,香蕉,都是对男性健康有益处的食物。你要是看不到价值,我可以告诉你。至少你能把看病节约下来的钱给你的女人多买几个DIOR.
18,力求上进的人,不要总想着靠谁谁,人都是自私的,自己才是最靠得住的人。
19,面对失败,不要太计较,天将降大任于斯人也,必先苦其心志,劳其筋骨,饿起体肤……但要学会自责,找到原因,且改掉坏习惯。 二十岁没钱,那很正常;三十岁没钱,那是宿命;四十岁没钱,那是你已经成为女人了。