项目压测优化

news2024/11/30 14:30:46

基本信息

客户名称:xxx

产品名称:ATS

版本号:版本无关

问题分类:性能问题

问题描述

        压测付款查询和收款查询接口,发现cpu过高,响应时间过长不符合要求。

        客户要求:1500并发情况下,接口响应时间2s以内,所有服务器的cpu占用在80%以下

问题解决

付款查询接口优化

        优化前:接口响应时间10s+,settlement和hub的服务器的cpu95%+

优化过程

1)优化组织查询,使用缓存

        先对hub做优化,给hub打jstack,查看线程的栈帧运行情况。

        发现tomcat活跃线程数有99个

        而98个线程都在执行OrganizationServiceImpl.getDirectChildOrg方法,

        经过排查该代码,发现调用该代码的地方没使用到缓存

        需要把this改成service自己注入自己的方式(this调用方法不能走到代理逻辑),改成self.getDirectChildOrg

        改完这里再次压测,发现响应时间变短,响应时间降到3.1s,settlement的cpu75%,hub的cpu80%

        由于客户对该接口要求是2s,需要继续优化,再给hub打jstack,发现大多数线程都卡在了等待redis结果上面。经确认后,客户使用1500并发压测,redis是单机,猜测可能redis处理遇到了瓶颈。

        考虑到组织的数据并不会频繁修改,这里其实可以用本地缓存,尝试把组织查询的代码改成本地缓存获取组织。过期时间给30s

        再次压测,响应时间变短,降低到2s,已经符合客户的要求,但是hub的cpu占用是80%,settlement的cpu占用90%+

        给hub打jstack,发现没有异常的堆栈了,根据cpu占用情况,后面优化settlement的代码

2)优化频繁获取字典翻译中environment中的属性导致锁竞争

        压测时给settlement打jstack,发现资源都在等待一个锁,

        分析后,是很多线程调用SpringContextHolder.getEnvironment().getProperty的时候,会走到jasypt包装的environment,这个加密插件获取属性值会走到如下的代码:

        多个线程调用compiteIfAbsent,会进行锁竞争。

        代码发现是字典翻译的时候,每次翻译都会走到获取属性的代码

        解决办法是不频繁去调用SpringContextHolder.getEnvironment().getProperty方法,每次启动项目的时候初始化一次即可。

        修改后进行压测,发现cpu没有降。

        可能是因为线程并发太高,即使没有该锁等待,也会给资源打满,去处理线程其他操作。

3)减少settlement中feign请求  

        再次打jstack,发现有不少线程在处理feign请求。发送大量网络请求可能会占用大量cpu。这里需要对feign请求做优化

        经过代码分析,一部分feign请求是在请求用户信息,这里的不能改,一部分feign是在AccountsUserInputParserImpl中频繁到hub中请求组织信息。

        这个service每次uc查询都会走到,所以并发很高的情况下可能会发大量feign请求。和上面hub对组织信息查询的优化一样,这里也加入本地缓存,不再频繁通过feign请求获取组织信息

        优化后hub的cpu降低,因为settlement请求hub的次数变少了,hub的cpu降到了65左右。因为减少了settlement对hub的feign调用次数。但是settlement的cpu还在89%左右。

4)优化框架中CustomInputParser的调用逻辑

        再次给settlement打jstack,发现发现大部分卡在了com.fingard.insurance.ats.settlement.biz.settlement.common.impl.AccountsUserInputParserImpl#customSqlParamValue的accountsUserMapper查询逻辑。

        分析这里的代码,发现CustomInputParser的调用有优化空间。

        每次uc查询都会调用所有的CustomInputParser,这里代码每次uc查询会给每个CustomInputParser调用两次,实际上只需要一次

        经过这里的优化后,发现响应时间和cpu都没有太大的改善。

5)使用arthas监控cpu消耗,对不合理的代码做优化(方法级别的CPU分析,前面主要是线程级别的)

        经过上面的优化,再打jstack,已经没有什么异常的栈了,基本都是每二三十个线程处理不一样的逻辑,所以通过jstack很难再找到可以对cpu资源占用有化的地方了。但是当前cpu占用还是有89%,目标是80%以下。这时就需要引入其他的工具,帮助我们找到压测过程中,cpu资源消耗在了哪些地方,找到cpu消耗最多的并且有优化空间的地方做优化。这里了解到arthas提供了这种功能,可以在现场部署arthas,监控压测过程,找到cpu消耗图。

具体使用情况:profiler | arthas     trace | arthas

这里主要使用了profiler命令。

火焰图的读法:如何读懂火焰图?

        直接把arthas-bin包发给现场,解压后执行java -jar arthas-boot.jar pid可以进入该java进程的操作。再使用profiler可以得到火焰图。

        分析火焰图,发现占用cpu的地方有一个处理是可以做优化的。

对应的代码:

        这里index的是".",可以去掉ignoreCase。

        这里优化后,客户现场反应达到要求了。

总结

        响应时间的优化,主要通过打jstack分析线程栈,找到阻塞的地方做优化。对cpu的优化也可以通过jstack来查看,如果没效果的话,可以引入arthas,通过火焰图查看cpu的消耗,找到对应代码做优化。付款查询的改动点主要是使用缓存,减少网络请求,优化代码重复调用的逻辑。

收款接口查询优化

场景:收款表数据量1亿500w

优化过程

        收款接口查询客户压测直接报超时了,先查看settlement的日志分析,发现报错都是在下面的地方:

        看上去像是AuthenticationFilter的报错,查看这里的代码,发现不管是超时异常还是其他异常,都会经过该filter写出response。所以这里基本确定是tomcat请求超时断开连接,在AuthenticationFilter写出了异常结果。

        让测试在页面上点击后,发现请求确实很慢,所以基本上是sql查询慢导致的

        查看慢查询:plsql直接执行下面sql

select *
 from (select sa.SQL_TEXT "执行 SQL",
        sa.EXECUTIONS "执行次数",
        round(sa.ELAPSED_TIME / 1000000, 2) "总执行时间",
        round(sa.ELAPSED_TIME / 1000000 / sa.EXECUTIONS, 2) "平均执行时间",
        sa.COMMAND_TYPE,
        sa.PARSING_USER_ID "用户ID",
        u.username "用户名",
        sa.HASH_VALUE
     from v$sqlarea sa
     left join all_users u
      on sa.PARSING_USER_ID = u.user_id
     where sa.EXECUTIONS > 0
     order by (sa.ELAPSED_TIME / sa.EXECUTIONS) desc)
 where rownum <= 50;

得到结果:

        发现收款查询的sql执行时间有180多秒,所以会连接超时。

        先从日志里拿到慢查询条件下的收款查询sql,直接在plsql里查询,发现执行很快。但是放到接口里查询很慢。

解决ORACLE PLSQL查询速度慢问题

        两者的区别是plsq里执行的sql是一个完整的sql,但是接口里执行查询的时候,用的是PreparedStatement设置参数查询的。可能在设置参数的时候影响了oracle的执行计划。一般产生这么大差异的情况都是有不合理的索引设置导致的,可以尝试对可疑索引(主要是一些区分度不高的索引)进行重建(如果索引有问题重建可能暂时解决问题,但是后面还会出现)或者删除来确认影响

这种情况下,主要操作了如下几个操作

  • plsql里执行sql,获取执行计划,对执行计划中的索引,和其他可能用到的索引做rebuild
alter index INDX_PAYMENTS_CHECKBATCHNO rebuild;

这里操作后发现没生效

  •  uc里的sql按照plsql里的执行计划强制使用这些索引

这里改完后发现还是没生效。

  • 再次分析表格中的其他索引,删掉不合理的索引

        这个接口刚好发现一个现象,页面上带上审批状态查询就慢,不带这个条件就很快,所以很怀疑是执行计划走到了大表格的审批状态的索引了。发现该1亿500w的表格中确实有审批状态的索引。

        因为审批状态样本数比较少,可能也就三四个值,所以是不太适合作为索引的。让现场删掉该索引

drop index IDX_T_RECMENTS_APPROVESTATE;

删除后发现生效了。页面查询优化到500ms了。

总结

        对于同样的一条sql,在plsql等工具中查询很快,uc接口中查询的慢的时候,有可能是PreparedStatement设置参数,导致服务端使用了不合理的执行计划

        遇到这种问题,可以使用重建索引和删除不合理的索引来解决。

收款任务运行失败

现象描述

        收款任务点运行后,运行一段时间报运行失败,settlement服务从nacos中消失。

问题解决

         先查看日志,发现现场没有完整的日志,只有这些连不上nacos的日志,是因为压测只开启了error级别日志。

        根据现象分析很像是settlement服务挂掉了,运行过程中服务挂掉就很有可能是中间发生了oom。于是让实施在启动参数中添加了-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/settlement.dump 的参数,作用是系统发生oom的时候,导出dump日志。

        重启后继续运行该任务,后面发生了上述现象,看tmp目录下确实导出了settlement.dump的文件,这里可以确定是发生了oom.分析该dump文件,查看哪些对象没被回收,这里通过mat做分析:

查看线程中占用的资源,发现一个查询的结果占用了大部分内存,查询的内容是RecmentPO列表。

        再查看下根据类型分组后的存活对象,发现就是该RecmentsPO类型的对象没被回收掉,占用了大概8g的资源 

        通过和测试确认后,正在压测的是收款任务接口,是比较明确的只有这一个接口在运行,所以直接查看收款任务的代码即可。如果是发生在正常运行的系统中,可以从线程资源占用中查看每个RecmentPO的属性数据,方便确认是哪里操作的该对象。

        查看收款任务接口,因为比较明确是查询结果中产生的RecmentsPO对象,所以关注该接口中的查询。

        最终发现有一个查询没有做分页,这里做了分批,但是粒度不够,每次查询可能会产生500w的对象,是这里导致的oom。

        解决方法时把收款任务中分批查询的sql再进行分页查询

总结

        查询时需要考虑每次查询大量数据的情况,对于可能存在查询出大量数据的接口需要做分页查询。

收款任务运行太慢

 现象描述

        收款任务是对几十万笔数据做收款,要求一个半小时完成,按照优化之前的代码跑,需要跑三个小时左右

问题解决

        首先需要确定收款方法在哪里性能损耗的最严重,可以使用arthas的trace命令,获取一个方法的n次调用中,每个操作的耗时。

trace的使用文档:https://arthas.aliyun.com/doc/trace.html

        但是trace只能获取方法的一层操作的执行时间。 这里选取收款的最顶层方法,即每一笔都去调用的方法,逐层获取执行最慢的地方

        trace com.fingard.insurance.ats.settlement.biz.settlement.recments.custom.AutoCollectionServiceImplForNCI batchCollectionNCI -n 1

Affect(class count: 1 , method count: 1) cost in 157 ms, listenerId: 6
`---ts=2023-03-08 20:08:45;thread_name=http-nio-9452-exec-4;id=5a;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@72503b19
    `---[29562.843ms] com.fingard.insurance.ats.settlement.biz.settlement.recments.custom.AutoCollectionServiceImplForNCI:batchCollectionNCI()
        +---[0.00% 0.048798ms ] com.fingard.insurance.ats.settlement.dto.innerapply.actdirecttransconfig.ActdirectpayconfigPO:getQuotacheckflag() #121
        +---[86.63% 25610.867091ms ] com.fingard.insurance.ats.settlement.biz.settlement.bussinesssupport.RecBussinessSupport:splitPayCommandsNCI() #129
        +---[0.00% 0.009251ms ] com.fingard.insurance.ats.settlement.common.settlement.enums.ATSSystemParamCodeEnum:getValue() #138
        +---[0.02% 4.736546ms ] com.fingard.insurance.ats.settlement.biz.settlement.cache.CacheService:getParamValueBycode() #138
        +---[0.00% min=9.04E-4ms,max=0.014765ms,total=1.26781ms,count=1000] com.baomidou.mybatisplus.core.conditions.query.QueryWrapper:<init>() #146
        +---[0.00% min=8.97E-4ms,max=0.011978ms,total=1.220209ms,count=1000] com.baomidou.mybatisplus.core.conditions.query.QueryWrapper:lambda() #146
        +---[0.00% min=8.86E-4ms,max=0.029558ms,total=1.240406ms,count=1000] com.fingard.insurance.framework.transaction.transfer.beans.transferDTO.MentsDTO:getSrcTransSN() #147
        +---[0.01% min=0.00153ms,max=0.035617ms,total=1.997444ms,count=1000] com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper:eq() #147
        +---[1.73% min=0.466338ms,max=7.909567ms,total=512.232536ms,count=1000] com.fingard.insurance.ats.settlement.dao.settlement.businessdetail.BusinessDetailMapper:selectList() #146
        +---[0.00% min=9.58E-4ms,max=0.027548ms,total=1.359497ms,count=1000] com.fingard.insurance.framework.transaction.transfer.beans.transferDTO.MentsDTO:setBusinessDetailDTOS() #158
        +---[0.00% 0.11444ms ] com.fingard.insurance.ats.settlement.common.settlement.utils.DateUtils:LocalDateTimeToUdate() #161
        +---[0.00% 0.077551ms ] cn.hutool.core.date.DateUtil:format() #161
        +---[0.00% 0.003683ms ] com.fingard.insurance.ats.settlement.common.settlement.utils.DateUtils:LocalDateTimeToUdate() #162
        +---[0.00% 0.047809ms ] cn.hutool.core.date.DateUtil:format() #162
        +---[0.00% 0.010023ms ] com.fingard.insurance.framework.transaction.transfer.sender.assistant.impl.Req9188Callback:<init>() #162
        +---[0.11% 31.236169ms ] com.fingard.insurance.framework.transaction.transfer.sender.assistant.impl.Req9188Callback:call() #162
        +---[0.00% 0.005069ms ] com.fingard.insurance.ats.settlement.dto.settlement.payments.PaycommandsPO:getReqbatchno() #163
        +---[0.02% 5.673377ms ] org.slf4j.Logger:info() #163
        +---[6.39% 1888.027604ms ] com.fingard.insurance.ats.settlement.common.settlement.utils.TransactionUtil:doInTransaction() #167
        +---[0.02% 6.895018ms ] org.slf4j.Logger:info() #172
        +---[0.00% 0.018818ms ] com.fingard.insurance.framework.transaction.transfer.beans.transferDTO.MentsDTO:getReqbatchno() #185
        +---[0.00% 0.029998ms ] org.slf4j.Logger:info() #191
        +---[0.00% 0.007468ms ] com.fingard.insurance.ats.settlement.common.utils.TransferUtil:<init>() #193
        +---[0.00% 0.005837ms ] com.fingard.insurance.framework.transaction.transfer.beans.response.Resp9188:<init>() #193
        +---[0.04% 11.935305ms ] com.fingard.insurance.ats.settlement.common.utils.TransferUtil:send() #193
        `---[3.44% 1017.620218ms ] com.fingard.insurance.ats.settlement.common.settlement.utils.TransactionUtil:doInTransaction() #194
 
Command execution times exceed limit: 1, so command will exit. You can set it with -n option.

可以看到是splitPayCommandsNCI方法执行时间最长,继续获取

 trace com.fingard.insurance.ats.settlement.biz.settlement.bussinesssupport.RecBussinessSupport splitPayCommandsNCI -n 1

Command execution times exceed limit: 1, so command will exit. You can set it with -n option.
 
esssupport.RecBussinessSupport splitPayCommandsNCI -n 1ent.biz.settlement.bussin
 
Press Q or Ctrl+C to abort.
 
Affect(class count: 1 , method count: 1) cost in 463 ms, listenerId: 7
 
`---ts=2023-03-08 20:11:41;thread_name=http-nio-9452-exec-4;id=5a;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@72503b19
 
    +---[0.005226ms] com.fingard.insurance.ats.settlement.common.settlement.enums.PayStateEnum:getValue() #1059
 
    `---[26141.03202ms] com.fingard.insurance.ats.settlement.biz.settlement.bussinesssupport.RecBussinessSupport:splitPayCommandsNCI()
 
   。。。。
 
        +---[76.87% min=15.22746ms,max=71.888338ms,total=20094.618296ms,count=1000] com.fingard.insurance.ats.settlement.biz.settlement.bussinesssupport.RecBussinessSupport:ReplenishPaycommands() #544
 
     。。。。
 
 
Command execution times exceed limit: 1, so command will exit. You can set it with -n option.

        看到是ReplenishPaycommands方法的问题,继续获取,需要注意的是ReplenishPaycommands是RecBussinessSupport父类的方法,需要trace对应父类的该方法

 trace  com.fingard.insurance.ats.settlement.biz.settlement.bussinesssupport.AbstractBussinessSupport ReplenishPaycommands -n 1

Affect(class count: 3 , method count: 2) cost in 799 ms, listenerId: 11
 
`---ts=2023-03-08 20:19:00;thread_name=http-nio-9452-exec-4;id=5a;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@72503b19
 
    `---[21.939317ms] com.fingard.insurance.ats.settlement.biz.settlement.bussinesssupport.AbstractBussinessSupport:ReplenishPaycommands()
 
  
        +---[21.69% 4.757752ms ] com.fingard.insurance.ats.settlement.biz.settlement.cache.CacheService:getDirectbankareacod() #508
 
.....
        +---[14.40% 3.158693ms ] com.fingard.insurance.ats.settlement.biz.settlement.cache.CacheService:getParamValueBycode() #530
 
.....
 
        +---[31.49% 6.909534ms ] com.fingard.insurance.ats.settlement.biz.settlement.cache.CacheService:getAccountsDtoByAccountnumber() #561
 
....

        可以看到是获取缓存的地方比较耗时,CacheService方法是从caffine中获取数据,正常来讲不应该到毫秒级别。所以定位到是这里的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1159463.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

BUUCTF 后门查杀 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 小白的网站被小黑攻击了&#xff0c;并且上传了Webshell&#xff0c;你能帮小白找到这个后门么&#xff1f;(Webshell中的密码(md5)即为答案)。 密文&#xff1a; 下载附件&#xff0c;解压得到一个网站文件夹。 解…

呼吸灯【FPGA】

晶振50Mhz 1us 等于 计0~49 1ms等于 0~999us 1s等于 0~999ms //led_outalways(posedge FPGA_CLK_50M_b5 or negedge reset_e8) //【死循环】敏感【触发条件&#xff1a;上升沿 clk】【运行副本】if(reset_e81b0)begin //50Mhz晶振&#xff0c; 49_999_999 是 1秒…

畅销书《Kali Linux高级渗透测试》更新版速速查收~

懒大王感谢大家的关注和三连支持~ 作者简介&#xff1a; 懒大王敲代码&#xff0c;正在学习嵌入式方向有关课程stm32&#xff0c;网络编程&#xff0c;数据结构C/C等 今天给大家推荐畅销书《Kali Linux高级渗透测试》&#xff0c;希望大家能觉得实用&#xff01; 欢迎大家点赞…

10.30寄存器,寄存器堆

寄存器 8位环形移位寄存器 module shift_regist (input wire clk,input wire rstn,input wire [7:0]D,output reg [7:0]Q ); always (posedge clk or negedge rstn) beginif(!rstn)Q<8b000000;elseQ<{D[6:0],D[7]} ; end endmodule //shift_regist 输入有时钟…

Qt入门日记1

目录 1.Qt简介和案例 2.第一个Qt程序 3.学会查看帮助文档 4.创建一个按钮 5.对象树简介 6.Qt的坐标系 7. 信号和槽 7.1自定义信号和槽 7.2信号连接信号 7.3拓展 7.4Qt4版本以前的connect 1.Qt简介和案例 Qt是一个跨平台的C图形用户界面应用程序框架(就是一个库吧…

2024“点点点”测试员如何上岸测试开发岗?附完整学习路线!

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

干货分享 | 一分钟带你了解TSMaster小程序编辑代码智能提示功能

本文给大家带来TSMaster小程序编辑的新功能&#xff0c;其中主要包含&#xff1a;代码编辑智能提示功能、可用外部代码编辑器编辑小程序代码并同步。 本文关键字&#xff1a;C小程序、Python小程序、代码智能提示、外部代码编辑器、Visual Studio 目录/Catalog ● TSMaster的…

11月1日星期三今日早报简报微语报早读

11月1日星期三&#xff0c;农历九月十八&#xff0c;早报微语早读分享。 1、神舟十六号航天员乘组平安抵京&#xff1b; 2、微信/抖音/B站等平台&#xff1a;将推动50万粉以上“自媒体”账号实名信息展示&#xff1b; 3、第三批鼓励仿制药品建议目录公示&#xff0c;包括抗癌…

灰狼优化算法(GWO)python

目录 一、灰狼优化算法的python实现 二、灰狼优化算法与遗传算法的对比分析&#xff08;python&#xff09; 2.1 GWO1.py 2.2 GA1.py 2.3 GWO_vs_GA.py 2.4 运行结果 ​三、基于莱维飞行改进的灰狼优化算法的python实现 一、灰狼优化算法的python实现 import numpy as …

报修软件有什么用?企业如何做好设备管理与维护?

在当今的商业环境中&#xff0c;设备设施的维护和管理已经成为企业运营的重要环节。无论是学校、酒店、物业等大型企事业单位&#xff0c;还是运维集成商、制造工厂等企业单位&#xff0c;都需要对设备设施进行有效的管理。报修软件作为一种智能化的解决方案&#xff0c;为设备…

钉钉会议室无需API开发轻松连接OA、电商、营销、CRM、用户运营、推广、客服等近千款系统

钉钉会议室支持成员管理、主持人权限管理、高级会控、组织内会议全员静音、共享权限控制等会议管理能力&#xff0c;确保会议安全可控的进行。 官网&#xff1a;https://page.dingtalk.com/wow/z/dingtalk/Rax/RoomsIntro 集简云无代码集成平台&#xff0c;轻松连接钉钉会议室…

专业软件测评中心▏App渗透测试的测试流程和注意事项简析

当前&#xff0c;我国数字经济蓬勃发展&#xff0c;为实现高质量发展注入了澎湃动力&#xff0c;App的需求和供给都十分旺盛&#xff0c;因此安全问题逐渐成为用户最为关注的话题之一&#xff0c;而渗透测试至关重要。 一、App渗透测试流程&#xff1a;   1、需求收集&#…

Vray3.6 for SketchUp安装失败错误如何处理?

SketchUp这款软件是一个极受欢迎并且易于使用的3D软件&#xff0c;有很多朋友会通过Sketchup建模或是Sketchup渲染操作。 Sketchup 建模渲染来说&#xff0c;也是较简单的一款软件&#xff0c;今天小编聊的话题不是Sketchup怎样渲染的操作。 而是对于一些新手朋友提到的关于V…

functools模块:让Python编程更高效

​​​​​​​ 概要 不知道小伙伴们在Python编程中&#xff0c;我们经常会遇到一些需要反复使用的代码片段&#xff0c;例如装饰器、高阶函数等。为了提高代码的复用性和可读性&#xff0c;Python提供了functools模块。functools模块包含了许多实用的功能&#xff0c;…

软文推广方案,媒介盒子分享

作为企业宣传的手段&#xff0c;它能用较低的成本获得较好的宣传效果&#xff0c;但有许多企业在进行软文推广时并不起效&#xff0c;这是因为没掌握好方法。今天媒介盒子就来告诉大家&#xff0c;通用的软文推广方案。 一、 明确推广目标以及受众 明确软文推广的目标有助于明…

数字化如何赋能企业降本增效?

在当前高度不确定的市场环境下&#xff0c;降本增效已成为传统企业热议的话题。在这个背景下&#xff0c;企业内部各种“卷”现象层出不穷&#xff0c;各部门都在积极降本、开源节流&#xff0c;同时也在争夺本就不足的企业资源。因此&#xff0c;数字部门在资源受限的情况下&a…

人工智能基础_机器学习016_BGD批量梯度下降求解多元一次方程_使用SGD随机梯度下降计算一元一次方程---人工智能工作笔记0056

然后上面我们用BGD计算了一元一次方程,那么现在我们使用BGD来进行计算多元一次方程 对多元一次方程进行批量梯度下降. import numpy as np X = np.random.rand(100,8) 首先因为是8元一次方程,我们要生成100行8列的X的数据对应x1到x8 w = np.random.randint(1,10,size = (8…

[移动通讯]【Carrier Aggregation-10】【 Radio Resource Control (RRC) Aspects】

前言&#xff1a; 参考《4G/LTE - LTE Advanced》 Carrier Aggregation is a special form of LTE technology that enables UE and Network to use more than one carrier frequencies. Actually this is not a new concept in LTE. You might have used/heard Dual Carrier …

Django3框架-(3)-[使用websocket]:使用channels实现websocket功能;简化的配置和实际使用方式

概述&#xff1a; 对于Django使用channels实现websocket的功能&#xff0c;之前就写了几篇博文了。随着在项目的使用和实际维护来说&#xff0c;重新设置了相关处理方法。 一般来说&#xff0c;前后端都只维护一个全局的连接&#xff0c;通过携带数据来判断具体的操作&#x…