当前位置: 首页 > news >正文

MVC架构模式学习笔记(动力节点老杜2022)

GitHub代码笔记:laodu-mvc: 动力节点学习javaweb中的mvc笔记。

文章目录

1.视频链接
2.不使用MVC架构模式程序存在的缺陷
3.MVC架构模式理论基础
4.JavaEE设计模式-DAO模式
5.pojo & bean & domain
6.业务层抽取以及业务类实现
7.控制层
8.MVC架构模式与三层架构的关系
9.手撕ThreadLocal源码
10.ThreadLocal的使用
11.不同功能的类放在不同的包下
12.层与层之间应该使用接口进行衔接以及当前项目存在的两大问题

 1 视频链接

JavaWeb课程导读_哔哩哔哩_bilibili


2 不使用MVC架构模式程序存在的缺陷

  • 在不使用MVC架构模式的前提下,完成银行账户转账。
  • 分析以下AccountTransferServlet他都负责了什么?
    • 1> 负责了数据接收
    • 2> 负责了核心的业务处理
    • 3> 负责了数据库表中数据的CRUD操作(Create【增】 Retrieve【查】 Update【改】 Delete【删】)
    • 4> 负责了页面的数据展示
  • 分析这个程序存在哪些问题?
    • 缺点1> 代码的复用性太差。(代码的重用性太差)
      • 导致缺点1的原因?
      • 因为没有进行“职能分工”,没有独立组件的概念,所以没有办法进行代码复用。代码和代码之间的耦合度太高,扩展力太差。
    • 缺点2> 耦合度高,导致了代码很难扩展。
    • 缺点3> 操作数据库的代码和业务逻辑混杂在一起,很容易出错。编写代码的时候很容易出错,无法专注业务逻辑的编写。

3 MVC架构模式理论基础


4 JavaEE设计模式-DAO模式

  • AccountDao是负责Account数据的增删改查的。
  • 什么是DAO?
    • Data Access Object(数据访问对象)
  • DAO实际上是一种设计模式,属于JavaEE的设计模式之一。(不是23种设计模式。)
  • DAO只负责数据库表的CRUD,没有任何业务逻辑在里面。
  • 没有任何业务逻辑,只负责表中数据增删改查的对象,有一个特殊的称谓:DAO对象。
  • 为什么叫做AccountDao呢?
    • 这是因为这个DAO是专门处理t_act这张表的。
    • 如果处理t_user表的话,可以叫做:UserDao
    • 如果处理t_student表的话,可以叫做:StudentDao
  • 一般情况下:一张表会对应一个DAO对象(pojo / bean / domain)。
  • DAO中的方法名很固定了,一般都是:
    • insert
    • deleteByXxx
    • update
    • selectByXxx
    • selectAll

5 pojo & bean & domain

  • 账户实体类:封装账户信息的。
  • 一般是一张表对应一个。
  • 这种普通简单的对象被成为pojo对象。
  • 有的人也会把这种专门封装数据的对象,称为bean对象。(javabean:咖啡豆)
  • 有的人也会把这种专门封装数据的对象,称为领域模型对象。domain对象。
  • 不同的程序员有不同的习惯。
public class Account { // 这种普通简单的对象被成为pojo对象。/*** 主键*/// 一般这种属性不建议设计为基本数据类型,建议使用包装类。防止null带来的问题。//private long id;private Long id;/*** 账号*/private String actno;/*** 余额*///private double balance;private Double balance;@Overridepublic String toString() {return "Account{" +"id=" + id +", actno='" + actno + '\'' +", balance=" + balance +'}';}public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getActno() {return actno;}public void setActno(String actno) {this.actno = actno;}public Double getBalance() {return balance;}public void setBalance(Double balance) {this.balance = balance;}public Account(Long id, String actno, Double balance) {this.id = id;this.actno = actno;this.balance = balance;}public Account() {}
}

6 业务层抽取以及业务类实现

  • service翻译为:业务。
  • AccountService:专门处理Account业务的一个类。
  • 在该类中应该编写纯业务代码。(只专注业务。不写别的。不和其他代码混合在一块。)
  • 只希望专注业务,能够将业务完美实现,少量bug。
  • 业务类一般起名:XxxService、XxxBiz…
public class AccountService {// 为什么定义到这里?因为在每一个业务方法中都可以需要连接数据库。private AccountDao accountDao = new AccountDao();// 这里的方法起名,一定要体现出,你要处理的是什么业务。// 我们要提供一个能够实现转账的业务方法(一个业务对应一个方法。)/*** 完成转账的业务逻辑* @param fromActno 转出账号* @param toActno 转入账号* @param money 转账金额*/public void transfer(String fromActno, String toActno, double money) throws MoneyNotEnoughException, AppException {// 查询余额是否充足Account fromAct = accountDao.selectByActno(fromActno);if (fromAct.getBalance() < money) {throw new MoneyNotEnoughException("对不起,余额不足");}// 程序到这里说明余额充足Account toAct = accountDao.selectByActno(toActno);// 修改余额(只是修改了内存中java对象的余额)fromAct.setBalance(fromAct.getBalance() - money);toAct.setBalance(toAct.getBalance() + money);// 更新数据库中的余额int count = accountDao.update(fromAct);// 模拟异常String s = null;s.toString();count += accountDao.update(toAct);if (count != 2) {throw new AppException("账户转账异常!!!");}}}

7 控制层

  • 账户小程序
  • AccountServlet是一个司令官。他负责调度其他组件来完成任务。
@WebServlet("/transfer")
public class AccountServlet extends HttpServlet { // AccountServlet作为Controllerprivate AccountService accountService = new AccountService();@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 接收数据String fromActno = request.getParameter("fromActno");String toActno = request.getParameter("toActno");double money = Double.parseDouble(request.getParameter("money"));try {// 调用业务方法处理业务(调度Model处理业务)accountService.transfer(fromActno, toActno, money);// 执行到这里了,说明成功了。// 展示处理结果(调度View做页面展示)response.sendRedirect(request.getContextPath() + "/success.jsp");} catch(MoneyNotEnoughException e) {// 执行到这里了,说明失败了。(余额不足)// 展示处理结果(调度View做页面展示)response.sendRedirect(request.getContextPath() + "/moneynotenough.jsp");} catch(Exception e){// 执行到这里了,说明失败了。response.sendRedirect(request.getContextPath() + "/error.jsp");}}
}

8 MVC架构模式与三层架构的关系


9 手撕ThreadLocal源码

public class Connection {
}
public class DBUtil {// 静态变量特点:类加载时执行,并且只执行一次。// 全局的大Map集合private static MyThreadLocal<Connection> local = new MyThreadLocal<>();/*** 每一次都调用这个方法来获取Connection对象* @return*/public static Connection getConnection(){Connection connection = local.get();if (connection == null) {// 第一次调用:getConnection()方法的时候,connection一定是空的。// 空的就new一次。connection = new Connection();// 将new的Connection对象绑定到大Map集合中。local.set(connection);}return connection;}}
package com.ycy.threadlocal;import java.util.HashMap;
import java.util.Map;/*** 自定义一个ThreadLocal类*/
public class MyThreadLocal<T> {/*** 所有需要和当前线程绑定的数据要放到这个容器当中*/private Map<Thread, T> map = new HashMap<>();/*** 向ThreadLocal中绑定数据*/public void set(T obj){map.put(Thread.currentThread(), obj);}/*** 从ThreadLocal中获取数据* @return*/public T get(){return map.get(Thread.currentThread());}/*** 移除ThreadLocal当中的数据*/public void remove(){map.remove(Thread.currentThread());}
}
package com.ycy.threadlocal;
// 张三发送请求,对应一个线程t1
// 李四发送请求,对应一个线程t2
public class Test {public static void main(String[] args) {Thread thread = Thread.currentThread();System.out.println(thread);// 调用serviceUserService userService = new UserService();userService.save();}
}
package com.ycy.threadlocal;public class UserService {private UserDao userDao = new UserDao();public void save(){Thread thread = Thread.currentThread();System.out.println(thread);Connection connection = DBUtil.getConnection();System.out.println(connection);userDao.insert();}}
package com.ycy.threadlocal;public class UserDao {public void insert(){Thread thread = Thread.currentThread();System.out.println(thread);Connection connection = DBUtil.getConnection();System.out.println(connection);System.out.println("User DAO insert");}
}


10 ThreadLocal的使用

JDK有ThreadLocal类的实现

public class DBUtil {private static ResourceBundle bundle = ResourceBundle.getBundle("resources/jdbc");private static String driver = bundle.getString("driver");private static String url = bundle.getString("url");private static String user = bundle.getString("user");private static String password = bundle.getString("password");// 不让创建对象,因为工具类中的方法都是静态的。不需要创建对象。// 为了防止创建对象,故将构造方法私有化。private DBUtil(){}// DBUtil类加载时注册驱动static {try {Class.forName(driver);} catch (ClassNotFoundException e) {e.printStackTrace();}}// 这个对象实际上在服务器中只有一个。private static ThreadLocal<Connection> local = new ThreadLocal<>();/*** 这里没有使用数据库连接池,直接创建连接对象。* @return 连接对象* @throws SQLException*/public static Connection getConnection() throws SQLException {Connection conn = local.get();if (conn == null) {conn = DriverManager.getConnection(url, user, password);local.set(conn);}return conn;}/*** 关闭资源* @param conn 连接对象* @param stmt 数据库操作对象* @param rs 结果集对象*/public static void close(Connection conn, Statement stmt, ResultSet rs){if (rs != null) {try {rs.close();} catch (SQLException e) {throw new RuntimeException(e);}}if (stmt != null) {try {stmt.close();} catch (SQLException e) {throw new RuntimeException(e);}}if (conn != null) {try {conn.close();// 思考一下:为什么conn关闭之后,这里要从大Map中移除呢?// 根本原因是:Tomcat服务器是支持线程池的。也就是说一个人用过了t1线程,t1线程还有可能被其他用户使用。local.remove();} catch (SQLException e) {throw new RuntimeException(e);}}}}
public class AccountService {// 为什么定义到这里?因为在每一个业务方法中都可以需要连接数据库。private AccountDao accountDao = new AccountDao();// 这里的方法起名,一定要体现出,你要处理的是什么业务。// 我们要提供一个能够实现转账的业务方法(一个业务对应一个方法。)/*** 完成转账的业务逻辑* @param fromActno 转出账号* @param toActno 转入账号* @param money 转账金额*/public void transfer(String fromActno, String toActno, double money) throws MoneyNotEnoughException, AppException {// service层控制事务try (Connection connection = DBUtil.getConnection()){System.out.println(connection);// 开启事务(需要使用Connection对象)connection.setAutoCommit(false);// 查询余额是否充足Account fromAct = accountDao.selectByActno(fromActno);if (fromAct.getBalance() < money) {throw new MoneyNotEnoughException("对不起,余额不足");}// 程序到这里说明余额充足Account toAct = accountDao.selectByActno(toActno);// 修改余额(只是修改了内存中java对象的余额)fromAct.setBalance(fromAct.getBalance() - money);toAct.setBalance(toAct.getBalance() + money);// 更新数据库中的余额int count = accountDao.update(fromAct);// 模拟异常String s = null;s.toString();count += accountDao.update(toAct);if (count != 2) {throw new AppException("账户转账异常!!!");}// 提交事务connection.commit();} catch (SQLException e) {throw new AppException("账户转账异常!!!");}}}
public class AccountDao {/*** 插入账户信息* @param act  账户信息* @return 1表示插入成功*/public int insert(Account act) {PreparedStatement ps = null;int count = 0;try {Connection conn = DBUtil.getConnection();String sql = "insert into t_act(actno, balance) values(?,?)";ps = conn.prepareStatement(sql);ps.setString(1, act.getActno());ps.setDouble(2, act.getBalance());count = ps.executeUpdate();} catch (SQLException e) {throw new RuntimeException(e);} finally {DBUtil.close(null, ps, null);}return count;}/*** 根据主键删除账户* @param id 主键* @return*/public int deleteById(Long id){PreparedStatement ps = null;int count = 0;try {Connection conn = DBUtil.getConnection();String sql = "delete from t_act where id = ?";ps = conn.prepareStatement(sql);ps.setLong(1, id);count = ps.executeUpdate();} catch (SQLException e) {throw new RuntimeException(e);} finally {DBUtil.close(null, ps, null);}return count;}/*** 更新账户* @param act* @return*/public int update(Account act) {PreparedStatement ps = null;int count = 0;try {Connection conn = DBUtil.getConnection();System.out.println(conn);String sql = "update t_act set balance = ? , actno = ? where id = ?";ps = conn.prepareStatement(sql);ps.setDouble(1, act.getBalance());ps.setString(2, act.getActno());ps.setLong(3, act.getId());count = ps.executeUpdate();} catch (SQLException e) {throw new RuntimeException(e);} finally {DBUtil.close(null, ps, null);}return count;}/*** 根据账号查询账户* @param actno* @return*/public Account selectByActno(String actno){PreparedStatement ps = null;ResultSet rs = null;Account act = null;try {Connection conn = DBUtil.getConnection();System.out.println(conn);String sql = "select id,balance from t_act where actno = ?";ps = conn.prepareStatement(sql);ps.setString(1, actno);rs = ps.executeQuery();if (rs.next()) {Long id = rs.getLong("id");Double balance = rs.getDouble("balance");// 将结果集封装成java对象act = new Account();act.setId(id);act.setActno(actno);act.setBalance(balance);}} catch (SQLException e) {throw new RuntimeException(e);} finally {DBUtil.close(null, ps, rs);}return act;}/*** 获取所有的账户* @return*/public List<Account> selectAll() {PreparedStatement ps = null;ResultSet rs = null;List<Account> list = new ArrayList<>();try {Connection conn = DBUtil.getConnection();String sql = "select id,actno,balance from t_act";ps = conn.prepareStatement(sql);rs = ps.executeQuery();while (rs.next()) {// 取出数据Long id = rs.getLong("id");String actno = rs.getString("actno");Double balance = rs.getDouble("balance");// 封装对象/*Account account = new Account();account.setId(id);account.setActno(actno);account.setBalance(balance);*/Account account = new Account(id, actno, balance);// 加到List集合list.add(account);}} catch (SQLException e) {throw new RuntimeException(e);} finally {DBUtil.close(null, ps, rs);}return list;}}

11 不同功能的类放在不同的包下

ssm里面一般都把dao包起名为mapper,把web包起名为controller

12 层与层之间应该使用接口进行衔接以及当前项目存在的两大问题

相关文章:

MVC架构模式学习笔记(动力节点老杜2022)

GitHub代码笔记&#xff1a;laodu-mvc: 动力节点学习javaweb中的mvc笔记。 文章目录 1.视频链接 2.不使用MVC架构模式程序存在的缺陷 3.MVC架构模式理论基础 4.JavaEE设计模式-DAO模式 5.pojo & bean & domain 6.业务层抽取以及业务类实现 7.控制层 8.MVC架构模式与三…...

docker常用操作-docker私有仓库的搭建(Harbor),并将本地镜像推送至远程仓库中。

1、docker-compose安装&#xff0c;下载docker-compose的最新版本 第一步&#xff1a;创建docker-compose空白存放文件vi /usr/local/bin/docker-compose 第二步&#xff1a;使用curl命令在线下载&#xff0c;并制定写入路径 curl -L "https://github.com/docker/compos…...

什么是MVC

MVC的全名是Model View Controller&#xff0c;是模型(model)&#xff0d;视图(view)&#xff0d;控制器(controller)的缩写&#xff0c;是一种软件设计典范。它是用一种业务逻辑、数据与界面显示分离的方法来组织代码&#xff0c;将众多的业务逻辑聚集到一个部件里面&#xff…...

ChatGPT浪潮来袭!谁先掌握,谁将领先!

任正非在接受采访时说 今后职场上只有两种人&#xff0c; 一种是熟练使用AI的人&#xff0c; 另一种是创造AI工具的人。 虽然这个现实听起来有些夸张的残酷&#xff0c; 但这就是我们必须面对的事实 &#x1f4c6; 对于我们普通人来说&#xff0c;我们需要努力成为能够掌握…...

Focal and Global Knowledge Distillation forDetectors

摘要 文章指出&#xff0c;在目标检测中&#xff0c;教师和学生在不同领域的特征差异很大&#xff0c;尤其是在前景和背景中。如果我们 平等地蒸馏它们&#xff0c;特征图之间的不均匀差异将对蒸馏产生负面影响。因此&#xff0c;我们提出了局部和全局蒸馏。局部蒸馏分离前景和…...

FX110网:1月美国零售货币资金环比上升2.61%,嘉盛环比上升1.86%

美国商品期货交易委员会&#xff08;CFTC&#xff09;发布的最新月度报告显示&#xff0c;2024年1月零售货币存款与上月相比上升2.61%。 这份报告涵盖在美国运营的注册零售货币对交易商&#xff08;RFED&#xff09;和经纪自营商。包括嘉信理财&#xff08;CHARLES SCHWAB Futu…...

全量知识系统的核心-全量知识的一个“恰当组织”的构想及百度AI答问

全量知识系统的核心-全量知识的一个恰当组织 Q1. 以下是对 我刚刚完成的文档“全量知识系统的核心&#xff1a;全量知识的一个恰当组织构想”的百度AI答复。由于字数400的限制&#xff0c;内容被分成四段. 第一次回答&#xff1a;学科和科学的框架 关于技术学科、一般学科和…...

C++中using 和 typedef 的区别

C中using 和 typedef 的区别_typedef using-CSDN博客 在C中&#xff0c;“using”和“typedef”执行声明类型别名的相同任务。两者之间没有重大区别。C中的“Using”被认为是类型定义同义词。此方法也称为别名声明。定义这些别名声明的工作方式类似于使用“using”语句定义C中…...

LeetCode-1944题: 队列中可以看到的人数(原创)

【题目描述】 有 n 个人排成一个队列&#xff0c;从左到右 编号为 0 到 n - 1 。给你以一个整数数组 heights &#xff0c;每个整数 互不相同&#xff0c;heights[i] 表示第 i 个人的高度。一个人能 看到 他右边另一个人的条件是这两人之间的所有人都比他们两人 矮 。更正式的&…...

Java基础面试题整理2024/3/13

1、可以使用switch的数据类型 Java5以前&#xff0c;switch(arg)表达式中&#xff0c;arg只能是byte、short、char、int。 Java5之后引入了枚举类型&#xff0c;也可以是枚举类型。 Java7开始引入了字符串类型。 2、Java中的goto有什么作用 goto是Java中的保留字&#xff0c…...

MachineSink - 优化阅读笔记

注&#xff1a;该优化与全局子表达式消除刚好是相反的过程&#xff0c;具体该不该做这个优化得看代价模型算出来的结果(有采样文件指导算得会更准确) 该优化过程将指令移动到后继基本块中&#xff0c;以便它们不会在不需要其结果的路径上执行。 该优化过程并非旨在替代或完全…...

虾皮shopee根据ID取商品详情 API

公共参数 名称类型必须描述keyString是免费申请调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中&#xff09;[item_search,item_get,item_search_shop等]cacheString否[yes,no]默认y…...

你知道数据库有哪些约束吗?

目录 1. NULL约束 2. 唯一&#xff08;UNIQUE&#xff09;约束 3. 默认值&#xff08;DEFAULT&#xff09;约束 4. 主键约束 5. 外键约束 6. CHECK约束 数据库约束是一种用于确保数据库中数据完整性和一致性的规则或条件。这些约束可以应用于表、列或整个数据库&#xff0…...

QT----基于QT的人脸考勤系统(未完成)

目录 1 编译opencv库1.1 下载源代码1.2 qt编译opencv1.3 执行Cmake一直卡着data: Download: face_landmark_model.dat 2 编译SeetaFace2代码2.1 遇到报错By not providing "FindOpenCV.cmake" in CMAKE_MODULE_PATH this project has2.2遇到报错Model missing 3 测试…...

机试:成绩排名

问题描述: 代码示例: #include <bits/stdc.h> using namespace std;int main(){cout << "样例输入" << endl; int n;int m;cin >> n;int nums[n];for(int i 0; i < n; i){cin >> nums[i];}// 排序for(int i 0; i < n; i){//…...

C编程基础四十分笔记

都是一些基础的C语言 一 输入一个整数&#xff0c;计算这个整数有几位二 编写程序计算一个分布函数三 输入一个字符串&#xff0c;再随便输入一个字母&#xff0c;判断这个字母出现几次四 求 1到10的阶乘之和五 求一个球体体积六 写一个链表&#xff0c;存1&#xff0c;2&#…...

k8s关于pod

目录 1、POD 的创建流程 kubectl 发起创建 Pod 请求&#xff1a; API Server 接收请求并处理&#xff1a; 写入 Etcd 数据库&#xff1a; Kubelet 监听并创建 Pod&#xff1a; Pod 状态更新和汇报&#xff1a; 2、POD 的状态解析 1. Pending Pod 2. Running Pod 3. S…...

yum安装mysql 数据库tab自动补全

centos7上面没有mysql&#xff0c;它的数据库名字叫做mariadb [rootlocalhost ~]#yum install mariadb-server -y [rootlocalhost ~]#systemctl start mariadb.service [rootlocalhost ~]#systemctl stop firewalld [rootlocalhost ~]#setenforce 0 [rootlocalhost ~]#ss -na…...

MBT-Net

feature F&#xff0c;edge feature E-F where r related to the relative position 辅助信息 作者未提供代码...

大数据赋能,能源企业的智慧转型之路

在数字洪流中&#xff0c;大数据已经成为推动产业升级的新引擎。特别是在能源行业&#xff0c;大数据的应用正引领着一场深刻的智慧转型。今天&#xff0c;我们就来探讨大数据如何在能源企业中发挥其独特的魅力&#xff0c;助力企业提效降本&#xff0c;实现绿色发展。 动态监控…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...