|  |      1Yoock      2020-12-16 22:10:13 +08:00 waitgroup | 
|      3fanyiaa      2020-12-16 22:19:59 +08:00 via Android c#里用 task 很容易。java 不知道有什么简便方法 | 
|      4Cbdy      2020-12-16 22:21:39 +08:00  4 let resultA const [resultB, resultC, resultD, resultE] = await Promise.all([a().then(ra => { resultA = ra; return b() }), c(), d(), e()]) | 
|  |      5Yoock      2020-12-16 22:23:33 +08:00 搜到一个 [CountDownLatch]( https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html) 不太了解 Java,你看一下 | 
|  |      6luxinfl OP 我想说的不是 AQS 方面的东西。是侧重于 java 微服务相关的 | 
|  |      7pkwenda      2020-12-16 22:45:45 +08:00 比如 zuul 网关应该可以写 groovy 从注册中心获取微服务,先调用啊,并发调用 cde,代码整合 kong 这种可以写 lua 插件 是这个意思吧,不进行并发处理延时是一样的 网关做 merge | 
|  |      8mango88      2020-12-16 23:49:08 +08:00 可以用几个 future,然后用 CompletableFuture.allOf() ,等所有 future 完成再去组装数据 | 
|      9xizismile      2020-12-16 23:51:10 +08:00 via Android 去看看 CompletableFuture 类 | 
|  |      10hangszhang      2020-12-16 23:59:11 +08:00 Java 的话, CompleteFuture 或者 RxJava 或者 Future | 
|  |      11DoctorCat      2020-12-17 01:57:50 +08:00 看起来是架构方案题,不是编程细节吧。b 调用 a,并降低时延,意味着 b 与 a 的调用链路最短+系统状态保持最优啊。如果分别部署在不同实例,那最好 b 与 a 同一个机架同一个子网,物理距离和网络逻辑位置最短的原则。 数据聚合最好设计一个数据聚合层比如引入 MQ 而且最好是 pubsub 机制……保持 tcp 长连接替代 HTTP 等等,还有 kernel 网络相关的调优、系统进程 CPU 亲和性的调优等等。 | 
|  |      12beidounanxizi      2020-12-17 02:33:21 +08:00 @luxinfl  go 的 waitgroup  Java 的 countdownlatch 都可以实现 , | 
|      13carlclone      2020-12-17 06:52:39 +08:00 via Android 这题难道不是考察分布式事务吗,楼上的都在讲什么乱七八糟的 | 
|      14noogler67      2020-12-17 08:44:47 +08:00 via iPhone 时延的话,就是同时发起 acde,等完成后再发起 b | 
|  |      15anthow      2020-12-17 08:55:52 +08:00 整几个 CompletableFuture | 
|      16Peachl      2020-12-17 09:00:55 +08:00  1 @carlclone 分布式事务是保证事务的 明显这个位置问的是如何做到顺序性的 completableFuture 就是正解 | 
|  |      17blessyou      2020-12-17 09:18:49 +08:00 js 的话大概是 Promise.all() | 
|      19liuhuan475      2020-12-17 09:41:56 +08:00 Future | 
|      20sonice      2020-12-17 09:55:47 +08:00  4 ``` CompletableFuture<String> futureAb = CompletableFuture.runAsync(() -> { // no operation }).thenApply(b-> "ab"); CompletableFuture<String> futureC = CompletableFuture.supplyAsync(() -> "c"); CompletableFuture<String> futureD = CompletableFuture.supplyAsync(() -> "d"); CompletableFuture<String> futureE = CompletableFuture.supplyAsync(() -> "e"); String collect = Stream.of(futureAb, futureC, futureD, futureE) .map(CompletableFuture::join) .collect(Collectors.joining(" ")); //output: ab c d e System.out.println(collect); ``` | 
|      21Cbdy      2020-12-17 10:35:42 +08:00 我是 4L,我把原先的 JS 版改成 Java 版 var resultList = Stream.of(CompletableFuture.supplyAsync(() -> a()).thenApply(ra -> Stream.of(ra, b())), CompletableFuture.supplyAsync(() -> c()), CompletableFuture.supplyAsync(() -> d()), CompletableFuture.supplyAsync(() -> e())) .map(CompletableFuture::join) .flatMap(it -> it instanceof Stream ? ((Stream<?>) it) : Stream.of(it)) .collect(Collectors.toList()); | 
|      22gmywq0392      2020-12-17 10:37:30 +08:00 回调 | 
|      23dddz97      2020-12-17 10:40:13 +08:00 感觉想问的点是 MQ 之类的 | 
|  |      24shyrock      2020-12-17 10:54:30 +08:00 插眼等有效回答。 | 
|  |      25qiaobeier      2020-12-17 10:58:19 +08:00 无非轮询事件回调。 | 
|  |      26fantastM      2020-12-17 11:39:18 +08:00 先同步调用 a,再用线程池异步并行地调用 bcde 。 因为整合数据时,需要保证 bcde 请求调用完成,所以就用一下 CountDownLatch 来实现这个等待机制。 | 
|      27XDJI      2020-12-17 14:36:03 +08:00 就是 20 21 解法 全链路异步 | 
|  |      28kkkkkrua      2020-12-17 14:40:27 +08:00 这不就是考察 CompletableFuture ? | 
|  |      30wangritian      2020-12-17 17:31:01 +08:00 a+b 一个 goroutine,cde 各一个 goroutine,主线程 waitgroup | 
|  |      31zy445566      2020-12-17 17:41:49 +08:00 如果是 js 的话,这样就行 ```js const data = await a(); const dataList = await Promise.all([c(),d(),d()]); // 整合数据 ``` | 
|      32Jooooooooo      2020-12-17 18:46:30 +08:00 20l 答案差不多了 | 
|      33liian2019      2020-12-17 19:01:54 +08:00 public static void test() throws Exception{ Map<String,String> resultMap = new HashMap<>(); CompletableFuture.allOf(CompletableFuture.supplyAsync(() -> { // 调用 A String aResult = "Hello"; resultMap.put("A",aResult); return aResult; }, executor).thenAcceptAsync(aResult -> { // 调用 B String bResult = aResult + " World"; resultMap.put("B",bResult); }), CompletableFuture.runAsync(() -> { // 调用 C String cResult = "CValue"; resultMap.put("C",cResult); },executor), CompletableFuture.runAsync(() -> { // 调用 D String dResult = "DValue"; resultMap.put("D",dResult); },executor), CompletableFuture.runAsync(() -> { // 调用 E String eResult = "EValue"; resultMap.put("E",eResult); },executor)).join(); System.out.println(JSON.toJSONString(resultMap)); } | 
|      34luvroot      2020-12-17 19:14:30 +08:00  1 ab 打包成一个微服务,ecd 做成 3 个微服务,即可 | 
|      35gengzi      2020-12-17 19:24:22 +08:00 多线程异步( Callable ),异步调用 a,调用 cde,等待 a 返回结果,再调用 b 。 最终的时延 acde 服务最长的一个耗时+b 服务耗时。 | 
|      36crclz      2020-12-17 19:30:22 +08:00 System.ReactiveX rxjs rxjava | 
|      37mxT52CRuqR6o5      2020-12-17 19:30:37 +08:00 就是在满足调用条件时就马上去调用,把这个逻辑写出来就行 | 
|  |      38Achieve7      2020-12-17 19:30:50 +08:00 CompletableFuture 或者 ForkJoinPool 都可以 如果是微服务 就异步呗 | 
|      39IssacTomatoTan      2020-12-17 19:42:57 +08:00 via Android Js: const f = new Promise(async (r)=>{ await a(); await b(); r(); }) promise.all([c,d,e,f]).then | 
|      40laminux29      2020-12-18 00:57:43 +08:00  1 微服务这功能,从本质上来说,首先是软件工程与管理上的问题,目的是为多人协同的大中型软件项目服务,是用增加组件间延时的代价来换取更快的平均运行性能与开发协作效率,所以时延高是必须,是代价,没办法从原理上降低。否则,如果低时延是刚需,那就不应该用微服务,而是单机 + 进程内部调用,这样子延时才会最小化。 其他细节上的问题,楼上的老哥们已经说了。 | 
|      41js8510      2020-12-18 08:45:14 +08:00 x->b and x->a pre call got b response, retrieve a response with the real ->a call 这样 是 max(x->b, x->a pre call) + x-a round trip 的时间 如果 a processing time 短于 b 还可以。 x->b and x->a precall b processing and then retrieve ->a response response x 这样的时间 和 x->a round trip + a prossing time 是一样的 | 
|  |      42mitsuizzz      2020-12-18 11:57:15 +08:00 20L 是我常用的方法,之前做过清理各个服务的数据,整合各个服务备份的脚本 | 
|  |      43519718366      2020-12-18 12:01:06 +08:00 via Android 其实面试回答,cde 异步请求就完事了… 在追问你怎么异步实现,当然优先微服务框架特性,再语言特性实现 |