SCRUM BOOT CAMP THE BOOK
スクラムについて一通り学べる。基礎編と実践編の二部構成になっている。
基礎編で用語や概念が説明され、実践編ではそれをどのように適用していけばよいかが説明されている。
座学で得られる限りの情報はこの本で学べるのではなかろうか。
特に実践編ではスクラムを現場にどのように導入していく様子が漫画のストーリで描かれており、イメージが付きやすい。
スクラム導入のための本としては良本。
while(true)と終了フラグで乗り切ってた汚い部分がだいぶきれいになった。import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.*; import java.util.function.Supplier; class FakeSearch implements Supplier<String>{ String name = null; public FakeSearch(String name){ this.name = name; } @Override public String get() { try { Thread.sleep((new Random().nextInt(10) * 1000)); }catch (Exception e){ } return name; } } public class CmpGoChannel2 { public static void First(Supplier<String> supplier1,Supplier<String> supplier2) throws Exception{ CompletableFuture<String> future1 = CompletableFuture.supplyAsync(supplier1); CompletableFuture<String> future2 = CompletableFuture.supplyAsync(supplier2); CompletableFuture<Object> future3 = CompletableFuture.anyOf(future1, future2); System.out.println(future3.get()); } public static void main(String... args) throws Exception{ FakeSearch web1 = new FakeSearch("Web1"); FakeSearch web2 = new FakeSearch("Web2"); FakeSearch image1 = new FakeSearch("Image1"); FakeSearch image2 = new FakeSearch("Image2"); FakeSearch video1 = new FakeSearch("Video1"); FakeSearch video2 = new FakeSearch("Video2"); CmpGoChannel2 c = new CmpGoChannel2(); List<Future<String>> list = new ArrayList<>(); First(web1,web2); First(image1,image2); First(video1,video2); } }
public static void First(Supplier<String> supplier1,Supplier<String> supplier2) throws Exception{ CompletableFuture<String> future1 = CompletableFuture.supplyAsync(supplier1); CompletableFuture<String> future2 = CompletableFuture.supplyAsync(supplier2); CompletableFuture<Object> future3 = CompletableFuture.anyOf(future1, future2); System.out.println(future3.get()); }
package main import ( "time" "math/rand" "fmt") var ( Web1 = fakeSearch("web1") Image1 = fakeSearch("image1") Video1 = fakeSearch("video1") Web2 = fakeSearch("web2") Image2 = fakeSearch("image2") Video2 = fakeSearch("video2") ) type Result string type Search func(query string) Result func fakeSearch(kind string) Search { return func(query string) Result { time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond) return Result(fmt.Sprintf("%s result for %q\n", kind, query)) } } func First(query string, replicas ...Search) Result { c := make(chan Result) searchReplica := func(i int) { c <- replicas[i](query) } for i := range replicas { go searchReplica(i) } return <-c } func Google(query string) (results []Result) { c := make(chan Result) go func() { c <- First(query, Web1, Web2) } () go func() { c <- First(query, Image1, Image2) } () go func() { c <- First(query, Video1, Video2) } () timeout := time.After(80 * time.Millisecond) for i := 0; i < 3; i++ { select { case result := <-c: results = append(results, result) case <-timeout: fmt.Println("timed out") return } } return} func main() { rand.Seed(time.Now().UnixNano()) start := time.Now() result := First("golang", fakeSearch("replica 1"), fakeSearch("replica 2")) elapsed := time.Since(start) fmt.Println(result) fmt.Println(elapsed) }
import java.util.ArrayList; import java.util.List; import java.util.concurrent.*; class Web1 implements Callable<String>{ public String call() { try { Thread.sleep(10*1000); }catch (Exception e){ } return "Web1"; } } class Web2 implements Callable<String>{ public String call() { return "Web2"; } } class Image1 implements Callable<String>{ public String call() { try { Thread.sleep(10*1000); }catch (Exception e){ } return "Image1"; } } class Image2 implements Callable<String>{ public String call() { return "Image2"; } } class Video1 implements Callable<String>{ public String call() { try { Thread.sleep(10*1000); }catch (Exception e){ } return "Video1"; } } class Video2 implements Callable<String>{ public String call() { return "Video2"; } } public class CmpGoChannel { public static void First(ExecutorService executor1,Callable<String> callable1, Callable<String> callable2) throws Exception{ List<Future<String>> list = new ArrayList<>(); list.add(executor1.submit(callable1)); list.add(executor1.submit(callable2)); boolean loopDone = false; while(true) { for (Future<String> f : list) { System.out.print("."); if (f.isDone()) { System.out.println(f.get()); loopDone = true; break; } } if(loopDone){ break; } } } public static void main(String... args) throws Exception{ ExecutorService executor1 = Executors.newFixedThreadPool(2); ExecutorService executor2 = Executors.newFixedThreadPool(2); ExecutorService executor3 = Executors.newFixedThreadPool(2); CmpGoChannel c = new CmpGoChannel(); List<Future<String>> list = new ArrayList<>(); Callable<String> web1 = new Web1(); Callable<String> web2 = new Web2(); First(executor1,web1,web2); Callable<String> image1 = new Image1(); Callable<String> image2 = new Image2(); First(executor2,image1,image2); Callable<String> video1 = new Video1(); Callable<String> video2 = new Video2(); First(executor3,video1,video2); executor1.shutdown(); executor2.shutdown(); executor3.shutdown(); } }
while(true) { for (Future<String> f : list) { System.out.print("."); if (f.isDone()) { System.out.println(f.get()); loopDone = true; break; } } if(loopDone){ break; } }