0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

异步神器CompletableFuture万字详解!

jf_ro2CN3Fa 来源:CSDN 作者:CSDN 2022-11-15 10:15 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群


CompletableFuture是jdk8的新特性。CompletableFuture实现了CompletionStage接口和Future接口,前者是对后者的一个扩展,增加了异步会点、流式处理、多个Future组合处理的能力,使Java在处理多任务的协同工作时更加顺畅便利。

一、创建异步任务

1. supplyAsync

supplyAsync是创建带有返回值的异步任务。它有如下两个方法,一个是使用默认线程池(ForkJoinPool.commonPool())的方法,一个是带有自定义线程池的重载方法

//带返回值异步请求,默认线程池
publicstaticCompletableFuturesupplyAsync(Suppliersupplier)

//带返回值的异步请求,可以自定义线程池
publicstaticCompletableFuturesupplyAsync(Suppliersupplier,Executorexecutor)

测试代码:

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf=CompletableFuture.supplyAsync(()->{
System.out.println("dosomething....");
return"result";
});

//等待任务执行完成
System.out.println("结果->"+cf.get());
}


publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
//自定义线程池
ExecutorServiceexecutorService=Executors.newSingleThreadExecutor();
CompletableFuturecf=CompletableFuture.supplyAsync(()->{
System.out.println("dosomething....");
return"result";
},executorService);

//等待子任务执行完成
System.out.println("结果->"+cf.get());
}

测试结果:

90bc4a4e-648a-11ed-8abf-dac502259ad0.png

2. runAsync

runAsync是创建没有返回值的异步任务。它有如下两个方法,一个是使用默认线程池(ForkJoinPool.commonPool())的方法,一个是带有自定义线程池的重载方法

//不带返回值的异步请求,默认线程池
publicstaticCompletableFuturerunAsync(Runnablerunnable)

//不带返回值的异步请求,可以自定义线程池
publicstaticCompletableFuturerunAsync(Runnablerunnable,Executorexecutor)

测试代码:

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf=CompletableFuture.runAsync(()->{
System.out.println("dosomething....");
});

//等待任务执行完成
System.out.println("结果->"+cf.get());
}


publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
//自定义线程池
ExecutorServiceexecutorService=Executors.newSingleThreadExecutor();
CompletableFuturecf=CompletableFuture.runAsync(()->{
System.out.println("dosomething....");
},executorService);

//等待任务执行完成
System.out.println("结果->"+cf.get());
}

测试结果:

90e0da4e-648a-11ed-8abf-dac502259ad0.png

3.获取任务结果的方法

//如果完成则返回结果,否则就抛出具体的异常
publicTget()throwsInterruptedException,ExecutionException

//最大时间等待返回结果,否则就抛出具体异常
publicTget(longtimeout,TimeUnitunit)throwsInterruptedException,ExecutionException,TimeoutException

//完成时返回结果值,否则抛出unchecked异常。为了更好地符合通用函数形式的使用,如果完成此CompletableFuture所涉及的计算引发异常,则此方法将引发unchecked异常并将底层异常作为其原因
publicTjoin()

//如果完成则返回结果值(或抛出任何遇到的异常),否则返回给定的valueIfAbsent。
publicTgetNow(TvalueIfAbsent)

//如果任务没有完成,返回的值设置为给定值
publicbooleancomplete(Tvalue)

//如果任务没有完成,就抛出给定异常
publicbooleancompleteExceptionally(Throwableex)

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

二、异步回调处理

1. thenApply和thenApplyAsync

thenApply 表示某个任务执行完成后执行的动作,即回调方法,会将该任务的执行结果即方法返回值作为入参传递到回调方法中,带有返回值。

测试代码:

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
return1;
});

CompletableFuturecf2=cf1.thenApplyAsync((result)->{
System.out.println(Thread.currentThread()+"cf2dosomething....");
result+=2;
returnresult;
});
//等待任务1执行完成
System.out.println("cf1结果->"+cf1.get());
//等待任务2执行完成
System.out.println("cf2结果->"+cf2.get());
}

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
return1;
});

CompletableFuturecf2=cf1.thenApply((result)->{
System.out.println(Thread.currentThread()+"cf2dosomething....");
result+=2;
returnresult;
});
//等待任务1执行完成
System.out.println("cf1结果->"+cf1.get());
//等待任务2执行完成
System.out.println("cf2结果->"+cf2.get());
}

测试结果:

9114db50-648a-11ed-8abf-dac502259ad0.png 914c3bd6-648a-11ed-8abf-dac502259ad0.png

从上面代码和测试结果我们发现thenApply和thenApplyAsync区别在于,使用thenApply方法时子任务与父任务使用的是同一个线程,而thenApplyAsync在子任务中是另起一个线程执行任务,并且thenApplyAsync可以自定义线程池,默认的使用ForkJoinPool.commonPool()线程池。

2. thenAccept和thenAcceptAsync

thenAccep表示某个任务执行完成后执行的动作,即回调方法,会将该任务的执行结果即方法返回值作为入参传递到回调方法中,无返回值。

测试代码

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
return1;
});

CompletableFuturecf2=cf1.thenAccept((result)->{
System.out.println(Thread.currentThread()+"cf2dosomething....");
});

//等待任务1执行完成
System.out.println("cf1结果->"+cf1.get());
//等待任务2执行完成
System.out.println("cf2结果->"+cf2.get());
}


publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
return1;
});

CompletableFuturecf2=cf1.thenAcceptAsync((result)->{
System.out.println(Thread.currentThread()+"cf2dosomething....");
});

//等待任务1执行完成
System.out.println("cf1结果->"+cf1.get());
//等待任务2执行完成
System.out.println("cf2结果->"+cf2.get());
}

测试结果:

915c4ad0-648a-11ed-8abf-dac502259ad0.png 917f8ce8-648a-11ed-8abf-dac502259ad0.png从上面代码和测试结果我们发现thenAccep和thenAccepAsync区别在于,使用thenAccep方法时子任务与父任务使用的是同一个线程,而thenAccepAsync在子任务中可能是另起一个线程执行任务,并且thenAccepAsync可以自定义线程池,默认的使用ForkJoinPool.commonPool()线程池。

3.thenRun和thenRunAsync

thenRun表示某个任务执行完成后执行的动作,即回调方法,无入参,无返回值。

测试代码:

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
return1;
});

CompletableFuturecf2=cf1.thenRun(()->{
System.out.println(Thread.currentThread()+"cf2dosomething....");
});

//等待任务1执行完成
System.out.println("cf1结果->"+cf1.get());
//等待任务2执行完成
System.out.println("cf2结果->"+cf2.get());
}

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
return1;
});

CompletableFuturecf2=cf1.thenRunAsync(()->{
System.out.println(Thread.currentThread()+"cf2dosomething....");
});

//等待任务1执行完成
System.out.println("cf1结果->"+cf1.get());
//等待任务2执行完成
System.out.println("cf2结果->"+cf2.get());
}

测试结果:

919bd614-648a-11ed-8abf-dac502259ad0.png91aa1882-648a-11ed-8abf-dac502259ad0.png

从上面代码和测试结果我们发现thenRun和thenRunAsync区别在于,使用thenRun方法时子任务与父任务使用的是同一个线程,而thenRunAsync在子任务中可能是另起一个线程执行任务,并且thenRunAsync可以自定义线程池,默认的使用ForkJoinPool.commonPool()线程池。

4.whenComplete和whenCompleteAsync

whenComplete是当某个任务执行完成后执行的回调方法,会将执行结果或者执行期间抛出的异常传递给回调方法,如果是正常执行则异常为null,回调方法对应的CompletableFuture的result和该任务一致,如果该任务正常执行,则get方法返回执行结果,如果是执行异常,则get方法抛出异常。

测试代码:

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
inta=1/0;
return1;
});

CompletableFuturecf2=cf1.whenComplete((result,e)->{
System.out.println("上个任务结果:"+result);
System.out.println("上个任务抛出异常:"+e);
System.out.println(Thread.currentThread()+"cf2dosomething....");
});

////等待任务1执行完成
//System.out.println("cf1结果->"+cf1.get());
////等待任务2执行完成
System.out.println("cf2结果->"+cf2.get());
}

测试结果:

91b85c44-648a-11ed-8abf-dac502259ad0.png

whenCompleteAsync和whenComplete区别也是whenCompleteAsync可能会另起一个线程执行任务,并且thenRunAsync可以自定义线程池,默认的使用ForkJoinPool.commonPool()线程池。

5.handle和handleAsync

跟whenComplete基本一致,区别在于handle的回调方法有返回值。

测试代码:

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
//inta=1/0;
return1;
});

CompletableFuturecf2=cf1.handle((result,e)->{
System.out.println(Thread.currentThread()+"cf2dosomething....");
System.out.println("上个任务结果:"+result);
System.out.println("上个任务抛出异常:"+e);
returnresult+2;
});

//等待任务2执行完成
System.out.println("cf2结果->"+cf2.get());
}

测试结果 :

91dba032-648a-11ed-8abf-dac502259ad0.png

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud
  • 视频教程:https://doc.iocoder.cn/video/

三、多任务组合处理

1. thenCombine、thenAcceptBoth 和runAfterBoth

这三个方法都是将两个CompletableFuture组合起来处理,只有两个任务都正常完成时,才进行下阶段任务。

区别:thenCombine会将两个任务的执行结果作为所提供函数的参数,且该方法有返回值;thenAcceptBoth同样将两个任务的执行结果作为方法入参,但是无返回值;runAfterBoth没有入参,也没有返回值。注意两个任务中只要有一个执行异常,则将该异常信息作为指定任务的执行结果。

测试代码:

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
return1;
});

CompletableFuturecf2=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf2dosomething....");
return2;
});

CompletableFuturecf3=cf1.thenCombine(cf2,(a,b)->{
System.out.println(Thread.currentThread()+"cf3dosomething....");
returna+b;
});

System.out.println("cf3结果->"+cf3.get());
}

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
return1;
});

CompletableFuturecf2=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf2dosomething....");
return2;
});

CompletableFuturecf3=cf1.thenAcceptBoth(cf2,(a,b)->{
System.out.println(Thread.currentThread()+"cf3dosomething....");
System.out.println(a+b);
});

System.out.println("cf3结果->"+cf3.get());
}

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf1dosomething....");
return1;
});

CompletableFuturecf2=CompletableFuture.supplyAsync(()->{
System.out.println(Thread.currentThread()+"cf2dosomething....");
return2;
});

CompletableFuturecf3=cf1.runAfterBoth(cf2,()->{
System.out.println(Thread.currentThread()+"cf3dosomething....");
});

System.out.println("cf3结果->"+cf3.get());
}

测试结果:

91f51922-648a-11ed-8abf-dac502259ad0.png9211a330-648a-11ed-8abf-dac502259ad0.png

92274e9c-648a-11ed-8abf-dac502259ad0.png 2.applyToEither、acceptEither和runAfterEither

这三个方法和上面一样也是将两个CompletableFuture组合起来处理,当有一个任务正常完成时,就会进行下阶段任务。

区别:applyToEither会将已经完成任务的执行结果作为所提供函数的参数,且该方法有返回值;acceptEither同样将已经完成任务的执行结果作为方法入参,但是无返回值;runAfterEither没有入参,也没有返回值。

测试代码:

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf1dosomething....");
Thread.sleep(2000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
return"cf1任务完成";
});

CompletableFuturecf2=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf2dosomething....");
Thread.sleep(5000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
return"cf2任务完成";
});

CompletableFuturecf3=cf1.applyToEither(cf2,(result)->{
System.out.println("接收到"+result);
System.out.println(Thread.currentThread()+"cf3dosomething....");
return"cf3任务完成";
});

System.out.println("cf3结果->"+cf3.get());
}


publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf1dosomething....");
Thread.sleep(2000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
return"cf1任务完成";
});

CompletableFuturecf2=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf2dosomething....");
Thread.sleep(5000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
return"cf2任务完成";
});

CompletableFuturecf3=cf1.acceptEither(cf2,(result)->{
System.out.println("接收到"+result);
System.out.println(Thread.currentThread()+"cf3dosomething....");
});

System.out.println("cf3结果->"+cf3.get());
}

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf1dosomething....");
Thread.sleep(2000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("cf1任务完成");
return"cf1任务完成";
});

CompletableFuturecf2=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf2dosomething....");
Thread.sleep(5000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("cf2任务完成");
return"cf2任务完成";
});

CompletableFuturecf3=cf1.runAfterEither(cf2,()->{
System.out.println(Thread.currentThread()+"cf3dosomething....");
System.out.println("cf3任务完成");
});

System.out.println("cf3结果->"+cf3.get());
}

测试结果:

92418438-648a-11ed-8abf-dac502259ad0.png925d7cc4-648a-11ed-8abf-dac502259ad0.png

从上面可以看出cf1任务完成需要2秒,cf2任务完成需要5秒,使用applyToEither组合两个任务时,只要有其中一个任务完成时,就会执行cf3任务,显然cf1任务先完成了并且将自己任务的结果传值给了cf3任务,cf3任务中打印了接收到cf1任务完成,接着完成自己的任务,并返回cf3任务完成;acceptEither和runAfterEither类似,acceptEither会将cf1任务的结果作为cf3任务的入参,但cf3任务完成时并无返回值;runAfterEither不会将cf1任务的结果作为cf3任务的入参,它是没有任务入参,执行完自己的任务后也并无返回值。

2. allOf / anyOf

allOf:CompletableFuture是多个任务都执行完成后才会执行,只有有一个任务执行异常,则返回的CompletableFuture执行get方法时会抛出异常,如果都是正常执行,则get返回null。

anyOf :CompletableFuture是多个任务只要有一个任务执行完成,则返回的CompletableFuture执行get方法时会抛出异常,如果都是正常执行,则get返回执行完成任务的结果。

测试代码:

publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf1dosomething....");
Thread.sleep(2000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("cf1任务完成");
return"cf1任务完成";
});

CompletableFuturecf2=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf2dosomething....");
inta=1/0;
Thread.sleep(5000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("cf2任务完成");
return"cf2任务完成";
});

CompletableFuturecf3=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf2dosomething....");
Thread.sleep(3000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("cf3任务完成");
return"cf3任务完成";
});

CompletableFuturecfAll=CompletableFuture.allOf(cf1,cf2,cf3);
System.out.println("cfAll结果->"+cfAll.get());
}


publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{
CompletableFuturecf1=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf1dosomething....");
Thread.sleep(2000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("cf1任务完成");
return"cf1任务完成";
});

CompletableFuturecf2=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf2dosomething....");
Thread.sleep(5000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("cf2任务完成");
return"cf2任务完成";
});

CompletableFuturecf3=CompletableFuture.supplyAsync(()->{
try{
System.out.println(Thread.currentThread()+"cf2dosomething....");
Thread.sleep(3000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("cf3任务完成");
return"cf3任务完成";
});

CompletableFuturecfAll=CompletableFuture.anyOf(cf1,cf2,cf3);
System.out.println("cfAll结果->"+cfAll.get());
}

		

测试结果:

9278b9a8-648a-11ed-8abf-dac502259ad0.png928fa848-648a-11ed-8abf-dac502259ad0.png

审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 接口
    +关注

    关注

    33

    文章

    9596

    浏览量

    157606
  • 线程
    +关注

    关注

    0

    文章

    510

    浏览量

    20868

原文标题:一网打尽:异步神器 CompletableFuture 万字详解!

文章出处:【微信号:芋道源码,微信公众号:芋道源码】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    同步复位和异步复位到底该用哪个

    做FPGA/数字IC设计的,平时写得最多的可能就是复位逻辑了。但你有没有这种感觉:看别人代码,有的用同步复位,有的用异步复位,有的又搞什么"异步复位同步释放"——到底该用哪个?
    的头像 发表于 04-22 09:42 353次阅读
    同步复位和<b class='flag-5'>异步</b>复位到底该用哪个

    淘宝券后价异步数据

    淘宝 券后价异步数据 ,核心是 非阻塞、批量、延迟获取 商品券后价(原价 - 优惠券),适合大规模商品监控、比价、选品场景。淘宝官方无直接 “券后价异步接口”,需通过 官方 API 组合 + 异步
    的头像 发表于 03-25 15:39 151次阅读

    低功耗电源管理神器——LTC2935 电压监视器详解

    低功耗电源管理神器——LTC2935 电压监视器详解 在电子设备的电源管理领域,低功耗、高精度、多功能的电压监视和复位功能是至关重要的。今天,我们就来深入探讨一下 Linear Technology
    的头像 发表于 02-27 11:45 398次阅读

    详解SRC4192和SRC4193:专业音频领域的异步采样率转换器

    详解SRC4192和SRC4193:专业音频领域的异步采样率转换器 在专业音频和广播应用的领域中,对音频信号处理的精度和灵活性要求极高。SRC4192和SRC4193这两款异步采样率转换器(ASRC
    的头像 发表于 02-03 16:00 745次阅读

    详解TL16C550C:高性能异步通信芯片的卓越之选

    详解TL16C550C:高性能异步通信芯片的卓越之选 在电子工程师的日常工作中,选择合适的通信芯片对于实现稳定、高效的异步通信至关重要。今天,我们就来深入探讨一款功能强大的异步通信芯片
    的头像 发表于 01-04 16:20 564次阅读

    异步电机零速满转矩输出问题详解

    异步电机在零速状态下实现满转矩输出是工业驱动领域的核心技术难题,其本质在于如何克服低速时转子电阻变化、磁链观测误差等固有特性。当电机静止时,传统V/f控制方式因定子电阻压降导致气隙磁通衰减,转矩输出
    的头像 发表于 01-04 07:36 688次阅读

    李飞飞万字长文:空间智能是AI的下一个十年

    1950年,当计算机不过是自动化算术和简单逻辑的代名词时,艾伦·图灵提出了一个至今仍有回响的问题:机器能思考吗?他以非凡
    的头像 发表于 11-19 21:20 1378次阅读
    李飞飞<b class='flag-5'>万字</b>长文:空间智能是AI的下一个十年

    万字长文AI智能体:17种体架构详细实现

    数据科学AI智能体领域发展迅猛,但许多资源仍然过于抽象和理论化。创建此项目的目的是为开发者、研究人员和AI爱好者提供一条结构化、实用且深入的学习路径,以掌握构建智能系统的艺术。
    的头像 发表于 11-07 13:16 742次阅读
    <b class='flag-5'>万字</b>长文AI智能体:17种体架构详细实现

    Redis Sentinel和Cluster模式如何选择

    在我十年的运维生涯中,见过太多团队在Redis集群方案选择上踩坑。有的团队盲目追求"高大上"的Cluster模式,结果运维复杂度爆表;有的团队死守Sentinel不放,最后扩展性成了瓶颈。今天,我想通过这篇万字长文,把我在生产环境中积累的经验全部分享给你。
    的头像 发表于 09-08 09:31 759次阅读

    3万字长文!深度解析大语言模型LLM原理

    我们正在参加全球电子成就奖的评选,欢迎大家帮我们投票~~~谢谢支持本文转自:腾讯技术工程作者:royceshao大语言模型LLM的精妙之处在于很好地利用数学解决了工业场景的问题,笔者基于过往工程经验继续追本溯源,与腾讯学堂合作撰写本文,尝试让人人都能懂大语言模型的基础原理。1、大语言模型简述截止到2025年“大模型”一般泛指“超大参数模型”,参数是指深度神经
    的头像 发表于 09-02 13:34 3610次阅读
    3<b class='flag-5'>万字</b>长文!深度解析大语言模型LLM原理

    万字全文科普:什么是IP?

    半导体行业在一个复杂且快速发展的生态系统中运作,并由持续创新驱动。该生态系统的核心是半导体价值链,它包含几个关键阶段:芯片设计、晶圆制造、最终组装和原材料采购。每个阶段对于半导体器件的生产和功能都至关重要。IP提供商在这一框架中发挥着关键作用,尤其是在芯片设计阶段,该阶段是整个价值链的基础。他们提供专业的尖端技术,以增强创新、促进无缝集成、确保合规性并加快产
    的头像 发表于 07-21 09:53 1321次阅读
    <b class='flag-5'>万字</b>全文科普:什么是IP?

    万字长文】物联网的激荡二十年

    2005年11月,在突尼斯举办的信息社会世界峰会(WSIS)上,国际电信联盟(ITU)发布了一份名为《ITU互联网报告2005:物联网》,正式向世人展示了什么是“物联网(InternetofThings)”。虽然业界一致认为,1999年,麻省理工学院的KevinAshton首次提出”物联网”这一术语,但仅仅只是一个理念,没有成体系的解释,也无法形成共识。而I
    的头像 发表于 06-27 13:42 1717次阅读
    【<b class='flag-5'>万字</b>长文】物联网的激荡二十年

    (ST大赛三等奖作品)超声波自拍神器实例项目

    (ST大赛三等奖作品)超声波自拍神器电路图:
    发表于 05-28 21:04

    MAX14830四通道串行UART,具有128FIFO技术手册

    MAX14830是一款先进的四通道通用异步收发器(UART),每路UART带有128先入/先出(FIFO)接收和发送缓存器,以及高速串行外设接口(SPI™)或I²C控制器接口。PLL和分数波特率发生器为波特率编程和参考时钟选择提供了极大灵活性。
    的头像 发表于 05-22 10:14 1215次阅读
    MAX14830四通道串行UART,具有128<b class='flag-5'>字</b>FIFO技术手册

    MAX3109双通道串行UART,带有128FIFO技术手册

    MAX3109先进的双通道通用异步收发器(UART)具有128收发先进/先出(FIFO)堆栈和高速SPI™或I²C控制器接口。2倍速和4倍速模式允许工作在最高24Mbps数据速率。锁相环(PLL)和分数波特率发生器允许灵活设置波特率、选择参考时钟。
    的头像 发表于 05-22 09:26 972次阅读
    MAX3109双通道串行UART,带有128<b class='flag-5'>字</b>FIFO技术手册