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

【JavaEE】TCP流套接字编程

目录

API

1.Socket类(客户端)

2.ServerSocket类(服务端)

创建回显服务器-客户端

服务器引入多线程

服务器引入线程池

解疑惑

长短连接


在Java中,TCP流套接字是基于TCP协议实现的网络通信方式,提供面向连接、可靠、有序的双向字节流传输。


API

TCP流套接字的核心API由java.net.Socket(客户端)和java.net.ServerSocket(服务端)组成

1.Socket类(客户端)

构造函数:

·Socket()

创建一个未连接的套接字,需手动调用connect(SocketAddress endpoint)

·Socket(String host,int port)

直接连接指定主机和端口,抛出UnkownHostException或IOException

·Socket(InetAddress address,int port)

使用InetAddress对象指定服务器地址,避免DNS解析

·Socket(String host,int port,InetAddress localAddr,int localPort)

绑定本地地址和端口,用于多网卡环境或指定出口IP

核心方法:

连接管理:

·connect(SocketAddress endpoint):手动建立连接

·isConnected():检查是否已连接

·InetAddress getInetAddress():返回套接字所连接的地址

·close():关闭套接字,释放资源

·数据流获取:

·InputStream getInputStream():获取输入流(读取服务器数据)

·OutputStream getOutputStream():获取输出流(发送数据到服务器)

·参数配置:

·setSoTimeout(int timeout):设置读写超时(毫秒),超时抛出SocketTimeoutException

·setSendBufferSize(int size):设置发送缓冲区大小(默认8KB)

·setReceiveBufferSize(int size):设置接收缓冲区大小(默认8KB)

·setTcpNoDelay(boolean on):禁用Nagle算法(默认false,启用延迟发送以提高数据包效率)

·setKeepAlive(boolean on):启用TCP KeepAlive机制(默认false)

示例代码:

try (Socket socket = new Socket("example.com", 80)) {socket.setSoTimeout(5000); // 5秒超时socket.setTcpNoDelay(true); // 禁用Nagle算法OutputStream out = socket.getOutputStream();out.write("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n".getBytes());InputStream in = socket.getInputStream();// 读取响应...
}

2.ServerSocket类(服务端)

构造函数

·ServerSocket(int port)

绑定指定端口,默认等待连接队列长度为50

·ServerSocket(int port,int backlog)

设置等待连接队列长度(backlog),避免客户端连接被拒绝

·ServerSocket(int port,int backlog,InetAddress bindAddr)

绑定到特定本地地址(如多网卡服务器指定监听IP)

核心方法

·监听与接受连接:

·accpet():阻塞等待客户端连接,返回Socket对象

·setReuseAddress(boolean on):允许端口在关闭后快速重用(默认false,避免BindException)

·参数配置:

·setSoTimeout(int timeout):设置accpet()方法的超时时间

·isClosed():检查是否已关闭

我们在学习完Socket和ServerSocket后,尝试写一个TCP的回显客户端/服务器

创建回显服务器-客户端

回显服务器--客户端:客户端发送什么请求,服务器便返回什么

回显服务器TcpEchoServer1

public class TcpEchoServer1 {ServerSocket serverSocket=null;public TcpEchoServer1(int port) throws IOException {serverSocket=new ServerSocket(port);}public void start() throws IOException {System.out.println("服务已启动");while(true){//服务器启动后 就开始接受客户端连接Socket clientSocket=serverSocket.accept();//处理接收processConnections(clientSocket);}}private void processConnections(Socket clientSocket) throws IOException {//打印连接信息System.out.printf("[%s:%d]客户端已连接\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());//读写数据try(InputStream inputStream=clientSocket.getInputStream()){try(OutputStream outputStream=clientSocket.getOutputStream()){//用Scanner处理更方便Scanner scanner=new Scanner(inputStream);//传入输入流,读取数据//循环获取请求while(true){//如果没有下一个数据就结束if(!scanner.hasNext()){System.out.printf("[%s:%d]客户端断开连接\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());break;}String request=scanner.next();//读取客户端的请求//处理数据String response=process(request);//把处理结果响应给客户端PrintWriter writer=new PrintWriter(outputStream);writer.println(response);writer.flush();//打印日志System.out.printf("[%s:%d]request:%s,response:%s\n",clientSocket.getInetAddress().toString(),clientSocket.getPort(),request,response);}}} catch (IOException e) {e.printStackTrace();}finally {//关闭SocketclientSocket.close();}}private String process(String request) {return request;}public static void main(String[] args) throws IOException {TcpEchoServer1 server=new TcpEchoServer1(9090);server.start();}
}

回显客户端TcpEchoClient1

public class TcpEchoClient1 {private Socket socket;//构造方法指定IP和端口号public TcpEchoClient1(String serverIp,int port) throws IOException {socket=new Socket(serverIp,port);}public void start(){System.out.println("连接服务器成功");//用socket.getInputStream获取try(InputStream inputStream=socket.getInputStream()){try(OutputStream outputStream=socket.getOutputStream()){Scanner scanner=new Scanner(System.in);while(true){//1.接收用户输入System.out.println("->");String request=scanner.next();//2.构造数据发送到服务器PrintWriter writer=new PrintWriter(outputStream);//写数据writer.println(request);
//强制刷新缓冲区,如果不刷新,客户端可能不能及时收到响应writer.flush();//3.接收服务器响应的数据Scanner resScanner=new Scanner(inputStream);String response=resScanner.next();//4.解析响应并打印System.out.printf("request:%s,response:%s\n",request,response);}}} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) throws IOException {TcpEchoClient1 client=new TcpEchoClient1("127.0.0.1",9090);client.start();}
}

服务器引入多线程

如果只是单个线程,无法同时响应多个客户端

此处给每个客户端都分配一个线程

客户端不做修改,只是在服务器处理客户端连接时,使用多线程去接收

代码如下:

public class TcpEchoServer2 {ServerSocket serverSocket=null;public TcpEchoServer2(int port) throws IOException {serverSocket=new ServerSocket(port);}public void start() throws IOException {System.out.println("服务已启动");while(true){//服务器启动后 就开始接受客户端连接Socket clientSocket=serverSocket.accept();//处理接收,每建立一个连接就创建一个线程取处理请求Thread t=new Thread(()->{try {processConnections(clientSocket);} catch (IOException e) {e.printStackTrace();}});t.start();}}

服务器引入线程池

为了避免频繁创建销毁线程,也可以引入线程池

这里如上,也只在服务器中进行修改。将创建多线程去接收客户端连接修改成:让线程池去提交请求,分配线程去处理客户端的请求

代码如下

public class TcpEchoServer {private ServerSocket serverSocket=null;//这里和UDP服务器类似,也是在构造对象的时候,绑定端口号public TcpEchoServer(int port) throws IOException {serverSocket=new ServerSocket(port);}public void start() throws IOException {System.out.println("启动服务器");//使用线程池管理线程ExecutorService executorService= Executors.newCachedThreadPool();while(true){//对于TCP来说,需要先处理客户端发来的连接//通过读写clientSocket,和客户端进行通信//如果没有客户端发起连接,此时accept就会阻塞//主线程负责进行accept。每次accept到一个客户端,就创建一个线程//由新线程负责处理客户端的请求Socket clientSocket=serverSocket.accept();executorService.submit(()->{processConnection(clientSocket);});}}

当大家逐一敲写代码后,可能会产生以下疑问?

解疑惑

1.服务器和客户端如何建立连接?我们这里简单讲解,后续会详细讲解(三次握手)

服务器在启动后,会阻塞等待连接(accpet方法)。

当客户端通过构造方法new Socket创建socket实例后,向服务器的serverSocket发起连接请求。

服务器接受连接,生成clientSocket(Socket clientSocket=serverSocket.accpet() )

通过服务器的clientSocket和客户端的socket进行网络通信

2.客户端从终端输入请求,服务端是如何获取请求的?

我们知道服务器和客户端分别通过clientSocket和socket进行网络通信

客户端发送请求:客户端通过PrintWriter将用户输入 写入输出流

outputStream=socket.getOutputStream();

PrintWriter writer=new PrintWriter(outputStream);

writer.println(request);//将字符串写入输出流

writer.flush();//强制刷新缓冲区,确保数据立即发送

服务端获取请求:

通过服务器的inputStream=clientSocket.getInputStream()获取客户端的输入流

然后根据

Scanner sc=new Scanner(inputStream);

String request=sc.next();

读取客户端的输入流(请求)

3.服务端根据请求返回响应,客户端又是如何获取响应的?

服务端返回响应:服务端也通过PrintWriter将响应 写入输出流

PrintWriter writer=new PrintWriter(outputStream);
String response=process(request);
writer.println(response);
writer.flush();

客户端获取响应:

通过客户端的inputStream=socket.getInputStream()获取服务器的输入流

然后根据

Scanner scanner=new Scanner(inputstream);

String response=scanner.next()

读取服务器的输入流(响应)

4.服务器的serverSocket、clientSocket和客户端的socket三者有何联系?

服务器

serverSocket:服务器端监听套接字

clientSocket:服务器端通信套接字。clientSocket是服务器为每个连接的客户端创建的专用套接字

数据传输:

通过clientSocket.getInputStream和getOutputStream与客户端交换数据

clientSocket在客户端连接时创建,连接断开时关闭

客户端

socket:客户端套接字

·发起连接:通过new Socket(服务器IP,端口)连接到服务器

·数据传输:通过socket.getInputStream和getOutputStream与服务器通信

socket在连接服务器后创建,通信接收后关闭

三者协作关系

1.连接建立

·客户端socket向服务器的serverSocket发起连接请求

·服务器serverSocket接受连接,生成一个clientSocket

2.数据传输

·客户端通过自身socket发送数据-->服务器通过对应的clientSocket接收数据

·服务器通过clientSocket发送响应-->客户端通过自身的socket接收响应

3.连接终止

·任意一端关闭套接字,连接即断开

·clientSocket和客户端socket关闭,但serverSocket继续监听新连接

5.Scanner与流(InputStream、OutputStream)的关系

输出流(OutputStream):用于发送数据(客户端--发送请求--服务端/服务端--返回响应--客户端)

输入流(InputStream):用于接收数据(服务端接收客户端的请求/客户端接收服务端的响应)

长短连接

TCP发送数据时,需要先建立连接,什么时候关闭连接就决定是短连接还是长连接:

短连接:每次接收到数据并返回响应后,就关闭连接,即是短连接。也就是说,短连接只能一次收发数据

长连接:不关闭连接,一直保持连接状态,双方不停的收发数据,即是长连接。也就是说,长连接可以多次收发数据

对比以上 长短连接,两者区别如下:

·建立连接、关闭连接的耗时:短连接每次请求、响应都需要建立连接,关闭连接;而长连接只需要第一次建立连接,之后的请求、响应都可以直接传输。相对来说,建立连接,关闭连接也是要耗时的,长连接效率更高

主动发送请求不同:短连接一般是客户端主动向服务端发送请求;而长连接可以是客户端主动发送请求,也可以是服务端主动发

两者的使用场景有不同:短连接适用于客户端请求频率不高的场景,如浏览网页等。长连接适用于客户端与服务端通信频繁的场景,如聊天室,实时游戏等

扩展了解

基于BIO(同步阻塞IO)的长连接会一直占用系统资源。对于并发要求很高的服务端系统来说,这样的消耗是不能承受的

由于每个连接都需要不停的阻塞等待接收数据,所以每个连接都会在一个线程中运行

一次阻塞等待 对应着一次请求、响应,不停处理也就是长连接的特性:一直不关闭连接,不停的处理请求

实时应用时,服务端一般是基于NIO(即同步非阻塞IO)来实现长连接,性能可以得到极大的提升

相关文章:

【JavaEE】TCP流套接字编程

目录 API 1.Socket类(客户端) 2.ServerSocket类(服务端) 创建回显服务器-客户端 服务器引入多线程 服务器引入线程池 解疑惑 长短连接 在Java中,TCP流套接字是基于TCP协议实现的网络通信方式,提供面向连接、可靠、有序的双向字节流传输。 API T…...

SQL问题分析与诊断(8)——分析方法1

8.4. 方法 8.4.1. 分析Cost方法 8.4.1.1. 方法说明 SQL Server中,通过阅读和分析SQL语句的评估查询计划,才是现实SQL优化工作中经常被采用的方法。然而,与Oracle等关系库类似,我们对SQL语句的查询计划进行阅读和分析时,首先要做的就是对SQL语句的整个查询计划进行快速的…...

【深度学习基础】神经网络入门:从感知机到反向传播

摘要 神经网络是深度学习的核心!本文将带你从零开始理解神经网络的基本原理,包括感知机模型、激活函数选择、反向传播算法等核心概念,并通过Python实现一个简单的全连接神经网络。文末提供《神经网络公式推导手册》和实战项目资源包&#xf…...

linux RCU技术

RCU(Read-Copy-Update)是Linux内核中的一种同步机制,用于在多核处理器环境中实现无锁读取和延迟更新。Linux RCU(Read-Copy-Update)技术通过一种高效的同步机制来处理并发冲突,确保在多核环境中读者和写者对…...

Hadoop文件操作指南:深入解析文件操作

1 Hadoop文件系统概述 Hadoop分布式文件系统(HDFS)是Hadoop生态的核心存储组件,专为大规模数据集设计,具有高容错性和高吞吐量特性。 HDFS核心特性: 分布式存储:文件被分割成块(默认128MB)分布存储多副本机制:每个块默认3副本&…...

【AI论文】VCR-Bench:视频链式思考推理的综合评估框架

摘要:思想链(CoT)推理的进步显著增强了大型语言模型(LLMs)和大型视觉语言模型(LVLMs)的能力。 然而,目前仍然缺乏一个严格的视频CoT推理评估框架。 目前的视频基准测试无法充分评估推…...

激光雷达点云动态目标剔除算法

剔除点云地图中动态目标的方法可分为基于体素、基于视点可见性和基于深度学习的方法。基于体素的方法通过点云地图体素占用率或点云地图体素与单帧点云数据差异剔除动态目标。 OctoMap算法在使用单帧点云数据构建点云地图的过程中,不断更新体素占用率,直…...

第五篇:Python面向对象编程(OOP)深度教程

1. 类与对象 1.1 基本概念 ​​类​​是创建对象的蓝图,定义了对象的​​属性​​(数据)和​​方法​​(行为)。​​对象​​是类的实例化实体,每个对象拥有独立的属性值和共享的类方法 ​​示例​​:定义Dog类 class Dog:species = "Canis familiaris" …...

Java IO精讲:从传统IO到NIO的深度探索

一、Java IO概述 Java IO(Input/Output) 是Java处理输入输出的核心API,涵盖文件操作、网络通信等场景。其发展分为三个阶段: 传统IO (java.io):基于流模型,阻塞式处理NIO (java.nio):New IO&a…...

效率工具- git rebase 全解

一、前言 对于git rebase 一直不太了解,这几天想着提高下git提交质量,就发现了这个好用的指令,顺便记录一下,好加深记忆 贴出官方文档以便大家进一步学习 Git 二、rebase是作用 rebase 官方解释为变基,可以理解为移动你的分支根节点,维护一个更好的提交记录。rebase把你当前…...

开启深度学习之旅

深度学习作为人工智能领域最激动人心的分支之一,正在改变我们与科技互动的方式。本文将为您提供深度学习的入门指南,帮助您踏上这一充满可能性的旅程。 一、深度学习基础概念 深度学习是机器学习的一个子集,它使用多层神经网络来模拟人脑的…...

JMeter的关联

关联:上一个请求的响应结果和下一个请求的数据有关系 xpath提取器 适用场景 HTML/XML文档结构化数据: 适用于从HTML或XML文档中提取结构化数据。例如,提取表格中的数据、列表中的项目等。示例:从HTML表格中提取所有行数据。 …...

jvm内存如何调优

以下是关于JVM内存调优的一些关键方法和最佳实践: 1. 堆内存配置 • 初始堆大小与最大堆大小: • 使用 -Xms 和 -Xmx 参数设置初始堆大小和最大堆大小。建议将两者设置为相同的值,以避免堆的动态扩展带来的性能开销。 • 堆内存大小通常建…...

[特殊字符] 第十四讲 | 空间异质性检验与地统计局部指标(LISA)应用

📌 关键词:空间异质性、LISA、局部Morans I、空间聚集、冷热点分析、GeoDa、R语言 🧠 导语:空间现象为何“不一样”? 在地理学与农学研究中,我们经常遇到“某地污染严重,而邻近区域却很轻微”的…...

【时时三省】(C语言基础)选择结构程序综合举例

山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 下面综合介绍几个包含选择结构的应用程序。 例题1: 写一程序,判断某一年是否为闰年。 程序1: 先画出判别闰年算法的流程图,见下图用变量le…...

【软考系统架构设计师】软件工程知识点

1、 软件开发生命周期 软件定义时期:包括可行性研究和详细需求分析过程,任务是确定软件开发工程必须完成的总目标,具体分为问题定义、可行性研究、需求分析等 软件开发时期:软件的设计与实现,分为概要设计、详细设计、…...

C#容器源码分析 --- Queue<T>

Queue<T> 是 System.Collections.Generic 命名空间下的先进先出&#xff08;FIFO&#xff09;动态集合&#xff0c;其核心实现基于​​循环数组​​&#xff0c;通过维护头尾指针实现高效入队和出队操作。 .Net4.8 Queue<T>源码地址&#xff1a;queue.cs (microso…...

redis 进阶

前篇 1&#xff0c;持久化 定义&#xff1a;将内存中的数据写入到磁盘&#xff0c;防止数据丢失——如果我门没有使用持久化技术&#xff0c;下次重新启动REDIS的时候只有空的redis没有任何东西 RDB 定义&#xff1a;在指定的时间间隔内将内存中的所有数据集以文件的形式写…...

python文件打包无法导入ultralytics模块

&#x1f4a5;打包的 .exe 闪退了&#xff1f;别慌&#xff01;教你逐步排查 PyInstaller 打包的所有错误&#xff01; &#x1f6e0; 运行 .exe 查看报错信息✅ 正确姿势&#xff1a; ⚠ importlib 动态导入导致打包失败❓什么是动态导入&#xff1f;✅ 解决方式&#xff1a; …...

c++清理内存

c清理内存 1.内存状态监控 实时显示物理内存/备用内存使用情况 2.单进程内存清理 清理当前进程工作集内存 3.系统级内存清理 清理备用列表、已修改页、组合列表 4.全局进程优化 强制清理所有进程的工作集 5.权限管理 启用调试权限以执行敏感操作 6.用户交互 控制台菜单操作与实…...

操作系统之进程同步

1.什么是进程同步&#xff0c;为什么要引入进程同步? 进程同步是指多个进程在执行次序上进行协调&#xff0c;使它们按一定的规则共享资源和相互合作。引入进程同步是为了避免并发进程因资源竞争而产生数据不一致、混乱等问题&#xff0c;确保系统的稳定性和正确性。 2.同步…...

论文精度:基于LVNet的高效混合架构:多帧红外小目标检测新突破

论文地址:https://arxiv.org/pdf/2503.02220 目录 一、论文背景与结构 1.1 研究背景 1.2 论文结构 二、核心创新点解读 2.1 三大创新突破 2.2 创新结构原理 2.2.1 多尺度CNN前端 2.2.2 视频Transformer设计 三、代码复现指南 3.1 环境配置 3.2 数据集准备 3.3 训…...

C语言--汉诺塔问题

汉诺塔问题是一个典型的递归问题。 递归问题的基本思想&#xff1a;将问题逐步化简为相同思路但是规模更小的问题&#xff0c;直到问题可以直接解决 递归的关键在于基准情形和递归步骤&#xff0c;基准情形也就是退出条件&#xff0c;递归步骤也就是把问题简化为子问题的过程。…...

深度剖析SSD多段L2P表查找加速技术

在固态硬盘(SSD)控制器中,逻辑块地址(LBA)需要通过映射表(L2P Table)映射到NAND闪存的物理地址(PA)。随着SSD容量的增长,L2P表的大小也随之增加,这给查找操作带来了性能挑战。 在SSD控制器中,LBA需借助L2P表映射为NAND物理地址。映射表最小规模为 (O(n * \lg (n)))…...

【sgSpliter】自定义组件:可调整宽度、高度、折叠的分割线

特性&#xff1a; 允许设置显示折叠按钮允许设置折叠线按钮位置允许设置当拖拽区域到0&#xff0c;再点击箭头展开的默认宽度允许设置当拖拽宽度小于此宽度&#xff0c;自动折叠到0允许设置指定最小宽度允许设置指定最大宽度允许设置按钮风格:白色背景default、蓝色背景blue允许…...

图像预处理-插值方法

一.插值方法 当我们对图像进行缩放或旋转等操作时&#xff0c;需要在新的像素位置上计算出对应的像素值。 而插值算法的作用就是根据已知的像素值来推测未知位置的像素值。 1.1 最近邻插值 CV2.INTER_NEAREST 其为 warpAffine() 函数的参数 flags 的其一&#xff0c;表示最近…...

Adruino:传感器及步进电机

一、传感器 1、温湿度传感器 DHT11它采用专用的数字采集技术和温湿度传感器技术&#xff0c;包括一个电阻式感湿元件和NTC测温元件&#xff0c;并与一个高性能的8位单片机连接。 (1).引脚介绍 名称解释VCC供电引脚3&#xff5e;5VGND接地引脚DATA串行数据单总线 二、电机 1…...

leetcode 2787. Ways to Express an Integer as Sum of Powers

题目描述 这道题是0-1背包问题。可以理解为&#xff0c;有一个最大容量是n的背包&#xff0c;有n个物品&#xff0c;第i个物品的重量是i^x&#xff0c;问装满背包有多少种装法。题目要求必须是互不相同的数的x次幂的和等于n&#xff0c;那就表示每个数只能用一次&#xff0c;也…...

React 获得dom节点和组件通信

通过REF 实例对象的.current属性获得绑定的DOM节点 组件通信 组件通信 1 父传子 父组件传递数据 子组件接受数据 通过pros对象接受 子组件的形参列表props只读 props中数据不可修改 特殊情况 在子传父的过程中没有直接给子组件添加属性&#xff0c;而是向父组件中添加其他…...

AF3 ProteinDataset类的get_anchor_ind方法解读

AlphaFold3 protein_dataset 模块 ProteinDataset 类 get_anchor_ind 方法是一个 @staticmethod 静态方法,用来获取“锚定残基(anchor residues)”的索引,目的是在蛋白质序列中被遮蔽(masked)的区域两端找到“已知(known)”的残基,以便后续作为上下文参考。 源代码:…...

JavaScript异常机制与严格模式

目录 JavaScript 异常机制 1. 基本语法&#xff1a;try...catch...finally 2. 抛出异常&#xff1a;throw 3. 错误对象属性 4. 同步代码的异常处理 5. 异步代码的异常处理 5.1 回调函数 5.2 Promise 5.3 全局未捕获的 Promise 错误 6. 全局错误处理 7. 自定义错误与…...

【数据结构与算法】包装类初识泛型

文章目录 一.包装类1.1基本数据类型和对应的包装类1.2装箱和拆箱1.3自动拆箱和自动装箱【面试题】 二.什么是泛型三.引出泛型3.1 语法 四. 泛型的使用4.1 语法格式4.2 示例4.3 类型推导(Type Inference) 五. 裸类型(Raw Type) &#xff08;了解即可&#xff09;5.1 说明 六. 泛…...

Linux--进程信号

目录 1. 信号快速认识 1-1 ⽣活⻆度的信号 1-2 技术应⽤⻆度的信号 1-2-1 ⼀个样例 1-2-2 ⼀个系统函数 1-3 信号概念 1-3-1 查看信号​编辑 1-3-2 信号处理 2. 产⽣信号 2-1 通过终端按键产⽣信号 2-1-1 基本操作 2-2 调⽤系统命令向进程发信号 2-3 使⽤函数产⽣…...

Skynet入门(二)

常用接口说明 接口说明newservice(name, …)启动一个name的新服务&#xff0c;并返回新服务的地址start(func)用func初始换服务。编写服务时&#xff0c;都会写一句skynet.start&#xff0c;并在func写一些初始化代码dispatch(type, func为type类型的消息设定处理函数funcsend…...

TDengine 可靠性保障:数据持久化与容灾备份(二)

四、容灾备份策略揭秘 &#xff08;一&#xff09;主从复制与故障转移 在 TDengine 的高可用性架构中&#xff0c;主从复制是一种极为关键的设计模式&#xff0c;它就像是数据的 “安全复制机”&#xff0c;将数据从主节点精准无误地复制到多个从节点 。在这个过程中&#xf…...

一文讲透大模型强化学习基础:PPO、DPO、GRPO

DeepSeek-R1 的强化学习方案中&#xff0c;其亮点之一在于通过 GRPO 算法取代RLHF 常用的 PPO&#xff0c;通过尽可能减少人类标注数据&#xff0c;设计纯 RL 的环境&#xff0c;用精心设计的奖励机制来训练模型自己学会推理。 那么什么是PPO、GRPO&#xff0c;其产生的背景、…...

第十六届蓝桥杯大赛软件赛省赛 Python 大学 B 组 部分题解

题面链接Htlang/2025lqb_python_b 个人觉得今年这套题整体比往年要简单许多&#xff0c;但是G题想简单了出大问题&#xff0c;预估50101015120860&#xff0c;道阻且长&#xff0c;再接再厉 A: 攻击次数 答案&#xff1a;103&#xff1f;181&#xff1f;题目没说明白每回合是…...

5分钟搭建一个在线客服网站!免费!

快速搭建在线客服网站完整教程 本文将手把手教你如何从零开始搭建一个功能完善的在线客服系统&#xff0c;整个过程简单快速&#xff0c;适合新手操作。 一、服务器选购指南 注册雨云账号 如果您尚未注册雨云账号&#xff0c;可以通过以下方式获取优惠&#xff1a; 注册链…...

【测试】-- 测试用例

文章目录 1. 测试用例1.1 概念 2. 设计测试用例的万能公式2.1 常规思考逆向思维发散性思维2.2 万能公式 3. 设计测试用例的方法3.1 具体的设计⽅法3.1.1 等价类3.1.2 边界值3.1.3 正交法3.1.3.1 如何设计正交表 3.1.4 判定表法3.1.4.1 根据判定表法设计测用例的步骤 3.1.5 场景…...

深度剖析循环码解码:从原理到纠错实践

一、引言 循环码作为线性分组码中的重要一员,凭借其出色的纠错和检测能力,在通信领域得到了广泛应用。本文将深入探讨循环码的解码过程,详细阐述其纠错和检测的机理。 二、循环码基础回顾 2.1 循环码的定义与性质 循环码是一类具有循环特性的线性分组码,即任一码组循环…...

MySQL面试题及答案,2025最新整理

文章目录 前言1.InnoDB 与 MyISAM 在事务和索引方面有哪些主要区别&#xff1f;2.简述 MySQL 的事务隔离级别及其对并发问题的解决情况&#xff1f;3.在使用 MySQL 索引时&#xff0c;如何避免索引失效&#xff0c;提高查询效率&#xff1f; 前言 本文围绕 MySQL面试题及答案&…...

ubuntu 安装pyllama教程

最近在研究motion gpt&#xff0c;有一个环节是需要下载gpt 13b&#xff0c;然后老是安装不上去pyllama&#xff0c;ubuntu的版本为&#xff1a; $ lsb_release -a LSB Version: core-11.1.0ubuntu4-noarch:security-11.1.0ubuntu4-noarch Distributor ID: Ubuntu Description…...

Python operator 模块介绍

operator 模块是 Python 标准库中的一个模块,它提供了一系列与 Python 内置运算符对应的函数。这些函数可以用于替代一些常见的运算符操作,在某些场景下能让代码更加简洁、高效,还能方便地用于函数式编程。以下是对 operator 模块的详细介绍: 1. 导入模块 使用 operator …...

[python] reduce

reduce 是 Python 中的一个高阶函数&#xff0c;用于对可迭代对象&#xff08;如列表、元组等&#xff09;中的元素进行累积计算&#xff0c;最终返回一个单一的结果。它位于 functools 模块中&#xff0c;使用时需要先导入&#xff1a; from functools import reduce 核心功能…...

ESP32与STM32哪种更适合初学者?

目录 1、ESP32&#xff1a;物联网时代的“网红” 2、STM32&#xff1a;工业界的“常青树” 3、到底谁更容易&#xff1f; 无论是刚入坑的小白&#xff0c;还是想扩展技术栈的老鸟&#xff0c;在选择主力 MCU 时&#xff0c;学习曲线绝对是重要的考量因素。ESP32 以其强大的 …...

AI编程案例拆解|基于机器学习XX评分系统-前端篇

文章目录 1. 定价使用DeepSeek估价小红书调研 2. 确定工作事项利用DeepSeek生成具体工作事项 3. 和客户沟通约会议沟通确定内容样式 4. 前端部分设计使用DeepSeek生成UI设计在Cursor中生成并提问前置条件开始编程 关注不迷路&#xff0c;励志拆解100个AI编程、AI智能体的落地应…...

十六届蓝桥杯嵌入式省赛直播基本外设驱动

前言 本文是准备2025年4月123日嵌入式蓝桥杯直播内容准备的一篇文章 1.创建工程 选择芯片 开启烧录引脚 开启高速时钟 主频设置成80回车 工程名称&#xff08;不能有中文&#xff0c;包括路径&#xff09; 考试的时候最下面哪一行取消勾选USE 然后选择这个文件夹打开 勾选几个…...

c_c++八股(一)

C/C static 静态局部变量&#xff08;函数内&#xff09; 使局部变量的生命周期延长至整个程序运行期间&#xff0c;但作用域仍限于函数内 变量只初始化一次&#xff0c;下次调用函数时保留上次的值 void counter() {static int count 0; // 只初始化一次count;printf(&quo…...

通过websocket给服务端发送订单催单提醒消息

controller层 GetMapping("/reminder/{id}")public Result Remainder(PathVariable("id") Long id){orderService.remainder(id);return Result.success();} 实现类 Overridepublic void remainder(Long id) {Orders ordersDB orderMapper.getById(id);…...

【NumPy科学计算引擎:从基础操作到高性能实践】

目录 前言&#xff1a;技术背景与价值当前技术痛点解决方案概述目标读者说明 一、技术原理剖析关键技术模块说明技术选型对比 二、实战演示环境配置核心代码实现运行结果验证 三、性能对比测试方法论量化数据对比结果分析 四、最佳实践推荐方案 ✅常见错误 ❌调试技巧 五、应用…...