跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 面试碰到一个问题,搞不定
未分類
29 12 月 2020

面试碰到一个问题,搞不定

面试碰到一个问题,搞不定

資深大佬 : luxinfl 11

比如说要调用 abcde 这五个微服务,调用 b 的前提是先调用 a,cde 没有这种顺序要求。最终数据要求整合。怎么才能让时延变小??
大佬有話說 (43)

  • 資深大佬 : Yoock

    waitgroup

  • 主 資深大佬 : luxinfl

    @Yoock 有 java 的实现么

  • 資深大佬 : fanyiaa

    c#里用 task 很容易。java 不知道有什么简便方法

  • 資深大佬 : Cbdy

    let resultA
    const [resultB, resultC, resultD, resultE] = await Promise.all([a().then(ra => { resultA = ra; return b() }), c(), d(), e()])

  • 資深大佬 : Yoock

    搜到一个 [CountDownLatch]( https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html)
    不太了解 Java,你看一下

  • 主 資深大佬 : luxinfl

    我想说的不是 AQS 方面的东西。是侧重于 java 微服务相关的

  • 資深大佬 : pkwenda

    比如 zuul 网关应该可以写 groovy 从注册中心获取微服务,先调用啊,并发调用 cde,代码整合
    kong 这种可以写 lua 插件
    是这个意思吧,不进行并发处理延时是一样的
    网关做 merge

  • 資深大佬 : mango88

    可以用几个 future,然后用 CompletableFuture.allOf() ,等所有 future 完成再去组装数据

  • 資深大佬 : xizismile

    去看看 CompletableFuture 类

  • 資深大佬 : hangszhang

    Java 的话, CompleteFuture 或者 RxJava 或者 Future

  • 資深大佬 : DoctorCat

    看起来是架构方案题,不是编程细节吧。b 调用 a,并降低时延,意味着 b 与 a 的调用链路最短+系统状态保持最优啊。如果分别部署在不同实例,那最好 b 与 a 同一个机架同一个子网,物理距离和网络逻辑位置最短的原则。
    数据聚合最好设计一个数据聚合层比如引入 MQ 而且最好是 pubsub 机制……保持 tcp 长连接替代 HTTP 等等,还有 kernel 网络相关的调优、系统进程 CPU 亲和性的调优等等。

  • 資深大佬 : beidounanxizi

    @luxinfl go 的 waitgroup Java 的 countdownlatch 都可以实现 ,

  • 資深大佬 : carlclone

    这题难道不是考察分布式事务吗,上的都在讲什么乱七八糟的

  • 資深大佬 : noogler67

    时延的话,就是同时发起 acde,等完成后再发起 b

  • 資深大佬 : anthow

    整几个 CompletableFuture

  • 資深大佬 : Peachl

    @carlclone 分布式事务是保证事务的 明显这个位置问的是如何做到顺序性的 completableFuture 就是正解

  • 資深大佬 : blessyou

    js 的话大概是 Promise.all()

  • 資深大佬 : TonyYOYO

    @fanyiaa 你可笑死我了

  • 資深大佬 : liuhuan475

    Future

  • 資深大佬 : sonice

    “`
    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);
    “`

  • 資深大佬 : Cbdy

    我是 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());

  • 資深大佬 : gmywq0392

    回调

  • 資深大佬 : dddz97

    感觉想问的点是 MQ 之类的

  • 資深大佬 : shyrock

    插眼等有效回答。

  • 資深大佬 : qiaobeier

    无非轮询事件回调。

  • 資深大佬 : fantastM

    先同步调用 a,再用线程池异步并行地调用 bcde 。

    因为整合数据时,需要保证 bcde 请求调用完成,所以就用一下 CountDownLatch 来实现这个等待机制。

  • 資深大佬 : XDJI

    就是 20 21 解法 全链路异步

  • 資深大佬 : kkkkkrua

    这不就是考察 CompletableFuture ?

  • 資深大佬 : surfire91

    @fantastM 为什么不先调用 acde,然后等 a 返回了再调 b

  • 資深大佬 : wangritian

    a+b 一个 goroutine,cde 各一个 goroutine,主线程 waitgroup

  • 資深大佬 : zy445566

    如果是 js 的话,这样就行
    “`js
    const data = await a();
    const dataList = await Promise.all([c(),d(),d()]);
    // 整合数据
    “`

  • 資深大佬 : Jooooooooo

    20l 答案差不多了

  • 資深大佬 : liian2019

    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));
    }

  • 資深大佬 : luvroot

    ab 打包成一个微服务,ecd 做成 3 个微服务,即可

  • 資深大佬 : gengzi

    多线程异步( Callable ),异步调用 a,调用 cde,等待 a 返回结果,再调用 b 。 最终的时延 acde 服务最长的一个耗时+b 服务耗时。

  • 資深大佬 : crclz

    System.ReactiveX rxjs rxjava

  • 資深大佬 : mxT52CRuqR6o5

    就是在满足调用条件时就马上去调用,把这个逻辑写出来就行

  • 資深大佬 : Achieve7

    CompletableFuture 或者 ForkJoinPool 都可以 如果是微服务 就异步呗

  • 資深大佬 : IssacTomatoTan

    Js:
    const f = new Promise(async (r)=>{
    await a();
    await b();
    r();
    })
    promise.all([c,d,e,f]).then

  • 資深大佬 : laminux29

    微服务这功能,从本质上来说,首先是软件工程与管理上的问题,目的是为多人协同的大中型软件项目服务,是用增加组件间延时的代价来换取更快的平均运行性能与开发协作效率,所以时延高是必须,是代价,没办法从原理上降低。否则,如果低时延是刚需,那就不应该用微服务,而是单机 + 进程内部调用,这样子延时才会最小化。

    其他细节上的问题,上的老哥们已经说了。

  • 資深大佬 : js8510

    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 是一样的

  • 資深大佬 : mitsuizzz

    20L 是我常用的方法,之前做过清理各个服务的数据,整合各个服务备份的脚本

  • 資深大佬 : 519718366

    其实面试回答,cde 异步请求就完事了…
    在追问你怎么异步实现,当然优先微服务框架特性,再语言特性实现

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具