springboot集成websocket实现实时大量数据,效率性能高

前言

小编我将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识,有兴趣的小伙伴可以关注一下!

也许一个人独行,可以走的很快,但是一群人结伴而行,才能走的更远!让我们在成长的道路上互相学习,让我们共同进步,欢迎关注!

针对websocket技术的金融alltick股票实战经验,通过调用第三方wss的的数据,来获取实时数据,并保持性能高及效率高

1、在springboot中引入websocket相应的jar包

  <!-- Spring Boot WebSocket Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>

2.创建webSocketConfig 暴露endpoint端点

package com.nq.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;@Configuration
public class WebSocketConfig  {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}}

3:创建websocket客户端用于连接第三方的wss

package com.nq.common;import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nq.pojo.Stock;
import com.nq.service.IStockService;
import com.nq.utils.PropertiesUtil;
import com.nq.utils.StringUtils;
import com.nq.utils.redis.RedisShardedPool;
import com.nq.utils.redis.RedisShardedPoolUtils;
import com.nq.vo.stock.StockListVO;
import com.nq.vo.websocket.CodeVo;
import com.nq.vo.websocket.StockVo;
import lombok.Data;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hpsf.Decimal;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.websocket.*;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URI;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;/*** @Description: websocket客户端* 一共2800条code产品数据,每个webSocketServer处理1000条数据,分三个webSocketServer处理* 提高效率* @Author: jade* @Date: 2021/8/25 10:25*/
@ClientEndpoint
@Slf4j
@Component   //交给spring容器管理
@Data
public class WebSocketJavaExample  {private Session session; //会话对象private Boolean flag = true; //用来拯救流的关闭标识符private Map<String,StockVo> stockVoMap;private  List<StockVo> stockList; //返回给客户端的封装数据List集合public final static Integer MAXCAP = 1000; //一次性以1000条@Resource  //使用@Resource来装配,不然会为nullIStockService stockService;private ObjectMapper objectMapper=new ObjectMapper();@OnOpenpublic void onOpen(Session session) {this.session = session;}
/**
接收第三方服务端的消息
**/@OnMessagepublic void onMessage(String message) {if(message.indexOf("data") != -1) {try {JSONObject jsonObject = JSONUtil.parseObj(message);String dataStr = jsonObject.getStr("data");//第三方响应的Json数据if (dataStr != null) {
//                    JSONArray jsonArray = JSONUtil.parseArray(dataStr);
//                    JSONObject jsonObject = JSONUtil.parseObj(dataStr);
//                    jsonArray.stream().forEach(item -> {JSONObject json = JSONUtil.parseObj(dataStr);Optional<StockVo> stockVo = stockList.stream()//Optional为java8的Stream API中使用,处理可能为null的元素.filter(p -> json.getStr("code").equals(p.getCode().concat(".US"))).findFirst();
//                                .filter(p -> json.getStr("code").equals(p.getCode())).findFirst();stockVo.ifPresent(vo -> {// 当前价格BigDecimal nowPrice = new BigDecimal(json.getStr("price"));BigDecimal preClosePrice = vo.getPreclose_px();vo.setType(json.getStr("trade_direction"));// alltick websocket 获取数据 替换原来的当前价格和涨幅vo.setNowPrice(nowPrice);// 计算涨幅BigDecimal chg = nowPrice.subtract(preClosePrice).divide(preClosePrice, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));vo.setHcrate(chg);});log.info("Optional<StockVo> send message to client"+stockVo);
//                    });} else {log.error("data字段不是一个有效的JSON数组: {}", dataStr);}} catch (Exception e) {log.error("解析消息时发生异常: {}", e.getMessage());}}}@OnClosepublic void onClose(Session session, CloseReason closeReason) {flag=false;log.info("AllTick API Docs流已关闭,关闭原因:{}",closeReason.toString());}@OnErrorpublic void onError(Throwable e) {log.error("AllTick API Docs连接异常{}",e.getMessage());}@Asyncpublic  void sendMessage(String key,String message) throws Exception {session.getBasicRemote().sendText(message);
//        log.info("client:{}, AllTick API Docs 请求报文: {}", key, message);
//        if (this.session != null && this.session.isOpen()) {
//            this.session.getBasicRemote().sendText(message);
//        } else {
//            log.error("会话已关闭,无法发送消息: {}", key);
//        }}//websocket地址private String url=PropertiesUtil.getProperty("WebSocket.url");//token数据private String token= PropertiesUtil.getProperty("WebSocket.token");public static List<WebSocketJavaExampleInfo> webSocketJavaExampleList = new ArrayList<>();@PostConstructpublic void  initPool() {new Thread(()->{   //另外起一个线程执行websocket,不影响主线程run();}).start();}@PreDestroypublic void destroy() {if (this.session != null && this.session.isOpen()) {try {this.session.close();} catch (IOException e) {log.error("关闭WebSocket连接时发生异常: {}", e.getMessage());}}}@Asyncpublic void run(){try {List<Stock> list = stockService.findStockList();int len = list.size();int capacity = (int) Math.ceil((double) len / MAXCAP);//向上取整
//            int capacity = (int) Math.ceil(len / MAXCAP);
//            if (capacity<1 || len % capacity != 0 ) {
//                capacity++;
//            }List<CodeVo> codeVos = new ArrayList<>();log.info("开始连接AllTick API Docs,请求url:{}",url.concat(token));WebSocketContainer container = ContainerProvider.getWebSocketContainer();URI uri = new URI(url.concat(token)); // Replace with your websocket endpoint URLfor (int i = 0; i < capacity; i++) {WebSocketJavaExample client = new WebSocketJavaExample(); //多个客户client执行,每个客户端执行1000条数据container.connectToServer(client, uri);List<Stock> list1 = list.stream().skip(i * MAXCAP).limit(MAXCAP).collect(Collectors.toList());stockList = new ArrayList<>();list1.forEach(item -> {CodeVo codeVo = new CodeVo();codeVo.setCode(item.getStockCode().concat(".US"));
//                            codeVo.setCode(item.getStockCode());codeVos.add(codeVo);StockVo stockVo = new StockVo();try {// 数据初始化String us = RedisShardedPoolUtils.get(item.getStockGid(), 4);StockListVO stockListVO = objectMapper.readValue(us, StockListVO.class);stockVo.setName(stockListVO.getName());stockVo.setCode(stockListVO.getCode());stockVo.setGid(stockListVO.getGid());stockVo.setStock_type(stockListVO.getStock_type());stockVo.setType(stockListVO.getType());stockVo.setHcrate(stockListVO.getHcrate());stockVo.setOpen_px(new BigDecimal(stockListVO.getOpen_px()));stockVo.setNowPrice(new BigDecimal(stockListVO.getNowPrice()));stockVo.setPreclose_px(new BigDecimal(stockListVO.getPreclose_px()));stockVo.setIsOption(Integer.valueOf(stockListVO.getIsOption()));stockList.add(stockVo);} catch (JsonProcessingException e) {log.info("redis数据转换对象stockListVO异常",e.getMessage());}});JSONArray symbolList = new JSONArray(codeVos); // 直接将List转换为JSONArrayclient.setStockList(stockList);// 使用LinkedHashMap来保持顺序Map<String, Object> messageMap = new LinkedHashMap<>();messageMap.put("cmd_id", 22004);messageMap.put("seq_id", 123);messageMap.put("trace", "3baaa938-f92c-4a74-a228-fd49d5e2f8bc-1678419657806");Map<String, Object> dataMap = new LinkedHashMap<>();dataMap.put("symbol_list", symbolList);messageMap.put("data", dataMap);// 将LinkedHashMap转换为JSONObjectJSONObject message2 = new JSONObject(messageMap);String message = message2.toString();
//                String message = "{\"cmd_id\":22004,\"seq_id\":123,\"trace\":\"3baaa938-f92c-4a74-a228-fd49d5e2f8bc-1678419657806\",\"data\":{\"symbol_list\": "+ JSONUtil.toJsonStr(codeVos) +"}}";client.sendMessage("client" + i, message);webSocketJavaExampleList.add(new WebSocketJavaExampleInfo(client, "client" + i,message));codeVos.clear();// 创建一个TimerTask任务int finalI = i;TimerTask task3 = new TimerTask() {@SneakyThrows@Overridepublic void run() {//定时获取心跳try {client.sendMessage("client" + finalI,"{\n" +"    \"cmd_id\":22000,\n" +"    \"seq_id\":123,\n" +"    \"trace\":\"3baaa938-f92c-4a74-a228-fd49d5e2f8bc-1678419657806\",\n" +"    \"data\":{\n" +"    }\n" +"}");} catch (Exception e) {log.error(e.getMessage());}}};new Timer().schedule(task3, 10000,10000);new Thread().sleep(2000);}}catch (Exception e){e.printStackTrace();log.error("AllTick API Docs 连接失败:{}",e.getMessage());}}
/**
定时任务,应用启动后延迟 2.5 分钟开始执行,之后每隔 2.5 分钟执行一次,去勘测是否流关闭,然后拯救连接websocket
**/@Scheduled(fixedRate = 1 * 15 * 10000,initialDelay = 150000)public void Daemon() throws Exception {WebSocketContainer container = ContainerProvider.getWebSocketContainer();URI uri = new URI(url.concat(token)); // Replace with your websocket endpoint URLfor(WebSocketJavaExampleInfo webSocketJavaExampleInfo:webSocketJavaExampleList){if(!webSocketJavaExampleInfo.getClient().flag){container.connectToServer(webSocketJavaExampleInfo.getClient(), uri);webSocketJavaExampleInfo.getClient().sendMessage(webSocketJavaExampleInfo.getKey(), webSocketJavaExampleInfo.getMessage());}}}
}@Data
class WebSocketJavaExampleInfo{private WebSocketJavaExample client;private String key;private String message;public WebSocketJavaExampleInfo(WebSocketJavaExample client, String key,String message) {this.client = client;this.key = key;this.message = message;}
}

4、创建websocket服务端用于连接客户端,及供前端访问

package com.nq.common;import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.nq.vo.websocket.StockVo;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.config.annotation.EnableWebSocket;import javax.annotation.PostConstruct;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;import static com.nq.common.WebSocketJavaExample.MAXCAP;
import static com.nq.common.WebSocketJavaExample.webSocketJavaExampleList;@ServerEndpoint("/ws/{userId}")
@EnableWebSocket
@Component
@Data
public class WebSocketServer {private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);private static final Integer pageSize = 100;//页码private Integer pageNo;//页数/*** concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。*/private static ConcurrentHashMap<String, WebSocketServer> webSocketMap = new ConcurrentHashMap<>();/*** 与某个客户端的连接会话,需要通过它来给客户端发送数据*/private Session session;/*** 接收userId*/private String userId = "";/*** 查询code*/private String code = "";/*** 连接建立成功调用的方法*/@OnOpenpublic void onOpen(Session session, @PathParam("userId") String userId) {this.session = session;this.userId = userId;if (webSocketMap.containsKey(userId)) {webSocketMap.remove(userId);webSocketMap.put(userId, this);} else {webSocketMap.put(userId, this);}}/*** 连接关闭调用的方法*/@OnClosepublic void onClose() {if (webSocketMap.containsKey(userId)) {webSocketMap.remove(userId);}}/*** 收到客户端消息后调用的方法** @param message 客户端发送过来的消息*/@OnMessagepublic void onMessage(String message, Session session) {log.info("用户消息:" + userId + ",报文:" + message);JSONObject jsonObject = JSONUtil.parseObj(message);
//        pageSize = jsonObject.getInt("pageSize");pageNo = jsonObject.getInt("pageNo");code = jsonObject.getStr("code");
//        if (ObjectUtil.isNotEmpty(code)) { //如果code不为空,则查询并推送数据
//            queryAndSendStockVo(code, session);
//        }}/*** @param session* @param error*/@OnErrorpublic void onError(Session session, Throwable error) {log.error("用户错误:" + this.userId + ",原因:" + error.getMessage());}/*** 实现服务器主动推送*/public void sendMessage(String message) throws IOException {this.session.getBasicRemote().sendText(message);}/*** 群发消息** @throws IOException*/@PostConstructpublic void BroadCastInfo() throws IOException, InterruptedException {log.info("开始轮询批量推送数据");ThreadUtil.execAsync(() -> {run();});}public void run() {WebSocketServer webSocketServer;List<StockVo> list = null;List<StockVo> additionalList = null;List<StockVo> list2 = null;while (true) {try {if (webSocketMap.size() > 0) {for (Map.Entry<String, WebSocketServer> stringWebSocketServerEntry : webSocketMap.entrySet()) {webSocketServer = stringWebSocketServerEntry.getValue();if (ObjectUtil.isEmpty(webSocketServer.pageNo) && ObjectUtil.isNotEmpty(webSocketServer.pageSize) && ObjectUtil.isEmpty(webSocketServer.getCode())) {//如果默认没有参数 就传输3千条
//                        if(ObjectUtil.isEmpty(webSocketServer.pageNo)) {//如果默认没有参数 就传输3千条list = webSocketJavaExampleList.get(0).getClient().getStockList().stream().limit(1000).collect(Collectors.toList());} else if (ObjectUtil.isNotEmpty(webSocketServer.pageNo)) {int pageSize = webSocketServer.pageSize;int pageNo = webSocketServer.pageNo;Integer size = pageNo * pageSize;
//                            int capacity = (int) Math.ceil(size / 20);int capacity = (int) Math.ceil(size / MAXCAP);int pageno = (capacity * 1000 / pageSize);pageNo -= pageno;if (capacity == 0) {list = webSocketJavaExampleList.get(capacity).getClient().getStockList().stream().skip(0).limit(pageNo * pageSize).collect(Collectors.toList());}if (capacity == 1) {list = webSocketJavaExampleList.get(0).getClient().getStockList().stream().collect(Collectors.toList());additionalList = webSocketJavaExampleList.get(capacity).getClient().getStockList().stream().skip(0).limit(size - (MAXCAP * capacity)).collect(Collectors.toList());list = Stream.concat(list.stream(), additionalList.stream()).collect(Collectors.toList());}if (capacity == 2) {list = webSocketJavaExampleList.get(0).getClient().getStockList().stream().collect(Collectors.toList());list2 = webSocketJavaExampleList.get(1).getClient().getStockList().stream().collect(Collectors.toList());additionalList = webSocketJavaExampleList.get(capacity).getClient().getStockList().stream().skip(0).limit(size - (MAXCAP * capacity)).collect(Collectors.toList());list = Stream.concat(Stream.concat(list.stream(), list2.stream()), additionalList.stream()).collect(Collectors.toList());}
//                            list = webSocketJavaExampleList.get(capacity).getClient().getStockList().stream().skip((pageNo - 1) * pageSize).limit(pageSize).collect(Collectors.toList());} else {String queryCode = webSocketServer.getCode();// 使用并行流处理数据,减少嵌套循环list = webSocketJavaExampleList.parallelStream().flatMap(webSocketJavaExampleInfo -> webSocketJavaExampleInfo.getClient().getStockList().stream()).filter(stockVo -> stockVo.getCode().contains(queryCode)).collect(Collectors.toList());}try {stringWebSocketServerEntry.getValue().sendMessage(JSONUtil.toJsonStr(list));} catch (IOException e) {log.error("用户编码为:{},推送ws数据异常,异常原因:{}", webSocketServer.getUserId(), e.getMessage());}}}} catch (Exception e) {log.error("推送失败: {}", e.getMessage());} finally {try {new Thread().sleep(2000);} catch (InterruptedException e) {log.error("没有客户端:{},webSocketMap:{}", e.getMessage(), webSocketMap.size());}}}}}

以上是基于小编在开发过程中,针对websocket技术的实战经验,通过调用第三方wss的的数据,来获取实时数据

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

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

相关文章

Python新春烟花

目录 系列文章 写在前面 技术需求 完整代码 下载代码 代码分析 1. 程序初始化与显示设置 2. 烟花类 (Firework) 3. 粒子类 (Particle) 4. 痕迹类 (Trail) 5. 烟花更新与显示 6. 主函数 (fire) 7. 游戏循环 8. 总结 注意事项 写在后面 系列文章 序号直达链接爱…

vscode 设置

一、如何在vscode中设置放大缩小代码 1.1.文件—首选项——设置 1.2.在搜索框里输入“Font Ligatures”&#xff0c;然后点击"在settings.json中编辑" 1.3.在setting中&#xff08;"editor.fontLigatures":前&#xff09;添加如下代码 "editor.mous…

航电系统路线规划克隆核心技术!

一、航电系统 航电系统&#xff08;Avionics System&#xff09;是民用飞机的“大脑”与“神经”&#xff0c;分为航电核心处理与数据传感两个部分。航电核心处理系统采用综合模块化、开放式系统结构&#xff0c;为飞机提供公共计算、网络通信和接口、飞行管理、显示与告警、机…

OSCP - Proving Grounds - BullyBox

主要知识点 如果发现有域名&#xff0c;则可以加入/etc/hosts后重新执行nmap,nikto等扫描dirsearch的时候可以使用完整一些的字典文件&#xff0c;避免漏掉信息.git dump 具体步骤 执行nmap 扫描&#xff0c;发现 80和22端口开放,访问后发现被重定向到 bullybox.local Star…

【计算机网络】传输层协议TCP与UDP

传输层 传输层位于OSI七层网络模型的第四层&#xff0c;主要负责端到端通信&#xff0c;可靠性保障&#xff08;TCP&#xff09;&#xff0c;流量控制(TCP)&#xff0c;拥塞控制(TCP)&#xff0c;数据分段与分组&#xff0c;多路复用与解复用等&#xff0c;通过TCP与UDP协议实现…

MongoDB 备份与恢复综述

目录 一、基本概述 二、逻辑备份 1、全量备份 2、增量备份 3、恢复 三、物理备份 1、cp/tar/fsync 2、WiredTiger 热备份 3、恢复 四、快照备份 一、基本概述 MongoDB 是一种流行的 NoSQL 数据库&#xff0c;它使用文档存储数据&#xff0c;支持丰富的查询语言和索引…

5. 马科维茨资产组合模型+AI金融智能体(qwen-max)+政策信息优化方案(理论+Python实战)

目录 0. 承前1. AI金融智能体1.1 What is AI金融智能体1.2 Why is AI金融智能体1.3 How to AI金融智能体 2. 数据要素&计算流程2.1 参数集设置2.2 数据获取&预处理2.3 收益率计算2.4 因子构建与预期收益率计算2.5 协方差矩阵计算2.6 投资组合优化2.7 持仓筛选2.8 AI金融…

后端开发基础——JavaWeb(Servlet)

Servlet 关于系统架构 系统架构包括什么形式&#xff1f; C/S架构 B/S架构 C/S架构&#xff1f; Client / Server&#xff08;客户端 / 服务器&#xff09; C/S架构的软件或者说系统有哪些呢&#xff1f; QQ&#xff08;先去腾讯官网下载一个QQ软件&#xff0c;几十MB&…

Hanlp的学习

参考&#xff1a;HanLP 自然语言处理使用总结-CSDN博客 参考&#xff1a;Sprint Boot 工程中HanLP配置相对路径&#xff0c;始终有问题的解决方案_springboot hanlp-CSDN博客 <!--hanlp 依赖--><dependency><groupId>com.hankcs</groupId><artifa…

LLMs(大型语言模型)的多智能体:Auto-GPT

LLMs(大型语言模型)的多智能体:Auto-GPT 是指在一个系统中集成多个具有不同能力、角色和任务的智能体,这些智能体能够相互协作、沟通和交互,以共同完成复杂的任务或解决复杂的问题。每个智能体都可以被视为一个独立的实体,具有自己的策略、目标和知识库,通过相互之间的…

JSON全解析:语法、转换与FastJson应用指南

大家好&#xff0c;我是袁庭新。JSON是一种轻量级、基于文本、开放式的数据交换格式。在数据交换的世界里&#xff0c;JSON 扮演着重要角色。它究竟为何备受青睐&#xff1f;下面就为您详细解读其奥秘与应用。 1.JSON简述 JSON&#xff08;JavaScript Object Notation&#…

Java模拟路由协议-rip(路由器仿真实验)

前言&#xff1a; 好久不见&#xff0c;有段时间没有写文章了&#xff0c;本篇文章&#xff0c;由Blue我带大家来复现rip协议。我们以 b站湖南教师匠所讲rip的视频中的例子为我这篇文章所模拟的路由路径 如图&#xff1a; 模拟路径 视频&#xff1a;http://【深入浅出计算机网络…

吴恩达深度学习——神经网络介绍

文章内容来自BV11H4y1F7uH&#xff0c;仅为个人学习所用。 文章目录 什么是神经网络引入神经网络神经元激活函数ReLU隐藏单元 用神经网络进行监督学习监督学习与无监督学习举例 什么是神经网络 引入 已经有六个房子的数据集&#xff0c;横轴为房子大小&#xff0c;纵轴为房子…

ChatGPT 摘要,以 ESS 作为你的私有数据存储

作者&#xff1a;来自 Elastic Ryan_Earle 本教程介绍如何设置 Elasticsearch 网络爬虫&#xff0c;将网站索引到 Elasticsearch 中&#xff0c;然后利用 ChatGPT 使用我们的私人数据来总结对其提出的问题。 Python 脚本的 Github Repo&#xff1a;https://github.com/Gunner…

数智化转型 | 星环科技Defensor 助力某银行数据分类分级

在数据驱动的金融时代&#xff0c;数据安全和隐私保护的重要性日益凸显。某银行作为数字化转型的先行者&#xff0c;面临着一项艰巨的任务&#xff1a;如何高效、准确地对分布在多个业务系统、业务库与数仓数湖中的约80万个字段进行数据分类和分级。该银行借助星环科技数据安全…

【JDBC】数据库连接的艺术:深入解析数据库连接池、Apache-DBUtils与BasicDAO

文章目录 前言&#x1f30d; 一.连接池❄️1. 传统获取Conntion问题分析❄️2. 数据库连接池❄️3.连接池之C3P0技术&#x1f341;3.1关键特性&#x1f341;3.2配置选项&#x1f341;3.3使用示例 ❄️4. 连接池之Druid技术&#x1f341; 4.1主要特性&#x1f341; 4.2 配置选项…

Linux Bash 中使用重定向运算符的 5 种方法

注&#xff1a;机翻&#xff0c;未校。 Five ways to use redirect operators in Bash Posted: January 22, 2021 | by Damon Garn Redirect operators are a basic but essential part of working at the Bash command line. See how to safely redirect input and output t…

C语言内存之旅:从静态到动态的跨越

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 引言正文一 动态内存管理的必要性二 动态…

AI时代:弯道超车的新思维与实践路径

大家好&#xff0c;我是herosunly。985院校硕士毕业&#xff0c;现担任算法研究员一职&#xff0c;热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名&#xff0c;CCF比赛第二名&#xff0c;科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的…

【Spring】定义的Bean缺少隐式依赖

问题描述 初学 Spring 时&#xff0c;我们往往不能快速转化思维。例如&#xff0c;在程序开发过程中&#xff0c;有时候&#xff0c;一方面我们把一个类定义成 Bean&#xff0c;同时又觉得这个 Bean 的定义除了加了一些 Spring 注解外&#xff0c;并没有什么不同。所以在后续使…