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

Java NIO基础与实战:如何提升IO操作性能

Java NIO 概述

Java NIO(新 I/O)是 Java 提供的一个更为高效的 I/O 处理框架。Java NIO(New I/O)是对传统 I/O(java.io)模型的改进,它引入了非阻塞 I/O 操作和面向缓冲区的数据读写方式,解决了传统 I/O 模型中的性能瓶颈。NIO 的设计目标是使 I/O 操作更加高效,特别是在大数据量、高并发情况下,能够充分利用操作系统的底层 I/O 多路复用机制。

Java NIO 的核心概念包括:Buffer(缓冲区)、Channel(通道)、Selector(选择器)。

这些组件使得 Java NIO 在处理大量并发连接时,能够减少线程的消耗,提高系统的吞吐量。

Java NIO 与传统 IO(BIO)的区别

区别维度BIDNIO
阻塞与非阻塞传统的阻塞 I/O 模型,线程在进行 I/O 操作时会被阻塞,直到操作完成。在处理多个连接时,可能会创建大量线程,每个线程处理一个连接。这种方式的缺点是线程的开销较大,且响应速度较慢。线程数过多导致上下文切换和内存消耗大,效率低。Java NIO 提供了非阻塞 I/O 模型。在 NIO 中,I/O 操作不会阻塞当前线程,线程可以发起请求并继续执行其他任务。通过选择器(Selector),一个线程可以管理多个通道,从而减少了线程的数量,降低了上下文切换的成本,能够更有效地利用系统资源。
I/O 模每个客户端连接都会占用一个线程,线程会被阻塞直到完成 I/O 操作。使用 Channel 和 Buffer 进行数据传输,通过 Selector 实现单线程管理多个连接。
实现方式通过 InputStream/OutputStream,每个线程处理一个 I/O 操作。通过 Channel 和 Buffer,数据读写通过缓冲区进行,提供了非阻塞的读写方式。

Java NIO 的核心组件

Channel

Channel 是 NIO 中的一个接口,表示可以进行 I/O 操作的对象。Channel 可以进行读取和写入操作。

常用的 Channel 类型有:

  • FileChannel:用于文件 I/O 操作。
  • SocketChannel:用于 TCP 网络 I/O 操作。
  • ServerSocketChannel:用于接收 TCP 客户端连接。
  • DatagramChannel:用于 UDP 网络 I/O 操作。

Channel 是 IO 通讯的通道,类似于 InputStream、OutputStream,但是 Channel 是没有方向性的。

获取方式
// FileInputStream/FileOutputStream
FileInputStream fis = new FileInputStream("example.txt");
FileChannel fileInputChannel = fis.getChannel();FileOutputStream fos = new FileOutputStream("example.txt");
FileChannel fileOutputChannel = fos.getChannel();// RandomAccessFile
RandomAccessFile raf = new RandomAccessFile("example.txt", "rw");
FileChannel randomAccessFileChannel = raf.getChannel();// FileChannel
FileChannel channel = FileChannel.open(Paths.get("example.txt"), StandardOpenOption.READ);// Socket
Socket socket = new Socket("localhost", 8080);
SocketChannel socketChannel = socket.getChannel();// ServerSocket
ServerSocket serverSocket = new ServerSocket(8080);
ServerSocketChannel serverSocketChannel = serverSocket.getChannel();// DatagramSocket
DatagramSocket datagramSocket = new DatagramSocket(8080);
DatagramChannel datagramChannel = DatagramChannel.open(); // 需独立创建
datagramChannel.bind(datagramSocket.getLocalSocketAddress());

Buffer

NIO 中的数据传输是基于缓冲区(Buffer)的。数据读写必须先存入缓冲区,然后通过 Channel 进行传输。

Channel 读取或者写入的数据,都要写到 Buffer 中,才可以被程序操作。

Buffer 有几种类型:ByteBuffer, MappedByteBuffer, CharBuffer, IntBuffer, DoubleBuffer, LongBuffer 等。

Buffer 的主要方法

  • put():将数据写入缓冲区。
  • get():从缓冲区读取数据。
  • flip():将缓冲区从写模式切换到读模式。
  • clear():清空缓冲区,其实只是状态的改变,并不会真正清空。
  • compact():将缓冲区中的未读数据向前移动,便于后续写操作。

因为 Channel 没有方向性,所以 Buffer 为了区分读写,引入了读模式、写模式进行区分。

写模式:新创建的 Buffer 就是写模式、调用 clear 方法清空后。

读模式:调用 flip 方法后。

获取方式
// 创建指定大小的缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);// 获取字符集,假设文件使用 UTF-8 编码
Charset charset = StandardCharsets.UTF_8;// 通过字符集获取
ByteBuffer encode = charset.encode("Hello, World!");

Selector

Selector 是 NIO 的一个核心组件,允许单线程通过轮询机制来监听多个 Channel 上的事件。Selector 通过轮询的方式检查是否有可用的 I/O 操作,从而避免了每个连接都占用一个线程。

Java NIO 的开发流程

  1. 获取 Channel
  2. 创建 Buffer
  3. 循环的从 Channel 中获取数据,读入到 Buffer 中。进行操作:
    1. channel.read(buffer);
    2. buffer.flip(); //设置读模式
    3. 循环从 buffer 中获取数据。
    4. buffer.get();
    5. buffer.clear(); //设置写模式

Java NIO 的工作流程

Java NIO 的工作流程可以分为以下几个步骤:

  1. 打开 Channel:通过 open() 方法打开相应的 Channel,如 FileChannelSocketChannel 等。
  2. 配置 Buffer:创建一个 Buffer 用于读写数据,Buffer 的大小通常是固定的,写入的数据首先会被写入 Buffer 中。
  3. 读写操作:通过 Channel 从文件或网络读取数据到 Buffer 中,或者将 Buffer 中的数据写入到 Channel
  4. Selector 监控:在非阻塞模式下,通过 Selector 监控多个 Channel 的状态。Selector 会返回一个就绪的 Channel,应用程序可以对其进行读写操作。
  5. 关闭 Channel:操作完成后,关闭 Channel 释放资源。

NIO 的主要优点

  • 非阻塞 I/O:传统的 I/O 操作是阻塞的,线程会一直等待数据的读取或写入,而 NIO 支持非阻塞 I/O,线程可以继续执行其他任务,而无需等待 I/O 操作完成。
  • 高并发:通过 Selector,NIO 允许单个线程管理多个 Channel,大大减少了线程的开销,提高了并发处理能力。
  • 高效内存管理Buffer 直接与内存进行交互,不像传统的 I/O 需要多次数据复制,减少了内存的消耗和处理的延迟。

示例:NIO/BIO 实现文件读取

BIO 实现

BIO(Blocking I/O)模型下,每次读取文件时,线程会被阻塞,直到完成读取操作。在传统的 BIO 中,我们通过 InputStream 来读取文件内容。下面是一个使用 BIO 方式读取文件的例子:

package fun.xuewei.nio.file;import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;/*** BIO 读取文件示例** @author 薛伟*/
public class BioFileReader {public static void main(String[] args) throws IOException {// 记录开始时间long startTime = System.nanoTime();// 使用传统的 BIO 读取文件FileInputStream fis = new FileInputStream("example.txt");BufferedReader reader = new BufferedReader(new InputStreamReader(fis));String line;while ((line = reader.readLine()) != null) {System.out.println(line); // 打印每一行}reader.close();fis.close();// 记录结束时间long endTime = System.nanoTime();System.out.println("\n\n\n");System.out.println("=============================================================");System.out.println("BIO 读取文件耗时: " + (endTime - startTime) / 1000000 + " 毫秒");System.out.println("=============================================================");}
}

在这段代码中:

  • 使用 BufferedReader 从文件流中逐行读取内容,直到文件结束。
  • 我们使用 System.nanoTime() 来记录开始和结束时间,以便测量执行时间。

NIO 实现

NIO 文件读取的方式使用 FileChannelByteBuffer,能够通过非阻塞的方式高效地处理 I/O 操作。你之前提供的代码就是一个 NIO 读取文件的示例。

package fun.xuewei.nio.file;import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;/*** NIO 读取文件示例** @author 薛伟*/
public class NioFileReader {public static void main(String[] args) throws IOException {// 记录开始时间long startTime = System.nanoTime();// 打开文件通道FileInputStream fis = new FileInputStream("example.txt");FileChannel fileChannel = fis.getChannel();// 创建缓冲区ByteBuffer buffer = ByteBuffer.allocate(1024);// 获取字符集,假设文件使用 UTF-8 编码Charset charset = StandardCharsets.UTF_8;// 读取文件内容到缓冲区while (fileChannel.read(buffer) > 0) {buffer.flip(); // 切换读模式while (buffer.hasRemaining()) {// 将字节缓冲区解码为字符并打印System.out.print(charset.decode(buffer).toString());}buffer.clear(); // 清空缓冲区,准备下次读取}fileChannel.close();fis.close();// 记录结束时间long endTime = System.nanoTime();System.out.println("\n\n\n");System.out.println("=============================================================");System.out.println("NIO 读取文件耗时: " + (endTime - startTime) / 1000000 + " 毫秒");System.out.println("=============================================================");}
}

在这段代码中:

  • 使用 FileChannelByteBuffer 从文件中读取内容。
  • 同样通过 System.nanoTime() 来记录执行时间。

测试并对比执行时间

这两段程序的差异在于文件读取的方式:

  • BIO 使用传统的阻塞式读取方式,一次从文件中读取一行,适合小文件或者连接数较少的场景。
  • NIO 使用 FileChannelByteBuffer,通过缓冲区和通道的组合进行读取,在处理大文件时能够更高效地读取数据。

分别运行上面两个程序可以得到下面的结果:

=============================================================
BIO 读取文件耗时: 243 毫秒
==========================================================================================================================
NIO 读取文件耗时: 59 毫秒
=============================================================

通过执行时间的比较,可以得出以下结论:

  • BIO:每次读取数据时,线程会被阻塞,直到读取完数据。对于每个 I/O 操作,都需要占用一个线程进行阻塞,性能较差。
  • NIO:通过缓冲区和通道的组合,能够在一个线程中高效地读取文件,并且避免了阻塞操作。在读取大文件时,NIO 的优势尤为明显,因为它可以更好地利用 CPU 和内存资源,减少线程的创建和上下文切换。

示例:NIO 实现零拷贝文件复制

在 Java NIO 中,通过利用 FileChannel 和操作系统提供的 零拷贝(Zero-Copy)机制,可以实现高效的文件复制。零拷贝指的是在数据传输过程中,不需要将数据复制到用户空间,而是直接在内核空间进行操作,减少了内存拷贝和 CPU 的消耗。

在文件复制的场景中,使用 FileChannel.transferTo()FileChannel.transferFrom() 可以实现零拷贝。这些方法直接将数据从一个通道传输到另一个通道,避免了中间缓冲区的创建和数据复制。

使用 transferTo() 方法进行零拷贝文件复制。FileChannel.transferTo() 方法允许将文件内容从一个 FileChannel 直接传输到另一个 FileChannel,通常用于文件复制。

示例代码

import java.io.*;
import java.nio.*;
import java.nio.channels.*;public class NioFileCopyZeroCopy {public static void main(String[] args) {// 源文件路径和目标文件路径String sourceFilePath = "source.txt";String destFilePath = "destination.txt";try (FileInputStream fis = new FileInputStream(sourceFilePath);FileOutputStream fos = new FileOutputStream(destFilePath)) {// 获取源文件和目标文件的 FileChannelFileChannel sourceChannel = fis.getChannel();FileChannel destChannel = fos.getChannel();// 使用 transferTo 实现零拷贝文件复制long position = 0; // 从文件的起始位置开始复制long size = sourceChannel.size(); // 获取源文件的大小long bytesTransferred = 0;// 执行零拷贝:从源文件到目标文件while (bytesTransferred < size) {bytesTransferred += sourceChannel.transferTo(position + bytesTransferred, size - bytesTransferred, destChannel);}System.out.println("文件复制完成!");} catch (IOException e) {e.printStackTrace();}}
}

代码解析

  1. 打开文件流和通道
    • FileInputStreamFileOutputStream 被用来读取和写入文件。
    • 通过 fis.getChannel() 获取源文件的 FileChannel,通过 fos.getChannel() 获取目标文件的 FileChannel
  2. transferTo 实现零拷贝复制
    • sourceChannel.transferTo(position, size, destChannel)FileChannel 提供的零拷贝复制方法。它会将源文件的内容从指定位置(position)复制到目标通道 destChannel,直到复制完指定大小的数据。
    • position 是文件的起始位置,size 是要复制的字节数。
    • 复制过程中,操作系统会直接在内核空间进行数据传输,减少了用户空间到内核空间的多次数据复制,从而提高了效率。
  3. 循环传输
    • 在实际操作中,如果文件很大,可能需要分段传输。通过循环传输数据,直到整个文件复制完成。
  4. 关闭资源
    • 使用 try-with-resources 语法自动关闭文件流和通道,确保资源释放。

零拷贝机制的优势

  • 性能提升:零拷贝减少了用户空间和内核空间之间的多次内存拷贝,降低了 CPU 的使用和内存消耗,特别是在传输大文件时,性能更为显著。
  • 高效数据传输:零拷贝直接在操作系统内核空间进行数据传输,避免了中间缓冲区的创建和数据拷贝过程,提高了数据传输速度。

注意事项

  1. 文件大小:当文件非常大时,零拷贝可以大大提升性能,因为它减少了不必要的内存拷贝操作。
  2. 操作系统支持:零拷贝是操作系统提供的功能,确保操作系统支持零拷贝机制。在 Linux 和 Unix 系统上,通常是默认支持的。Windows 操作系统也支持 transferTo()transferFrom() 方法,但实现细节可能有所不同。
  3. 异常处理:实际使用时,注意添加适当的异常处理逻辑,确保文件流和通道的正确关闭。

示例:NIO/BIO 客户端与服务器通信

BIO 版本:客户端与服务器通信

BIO 模型下,每个连接都会在一个独立的线程中进行处理,线程会阻塞直到 I/O 操作完成。以下是使用 BIO 实现的客户端与服务器通信的代码。

BIO 服务器端
package fun.xuewei.nio.network;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;/*** BIO 服务器端** @author 薛伟*/
public class BioServer {public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(8080);System.out.println("BIO 服务器启动,等待连接...");while (true) {// 阻塞直到有客户端连接Socket clientSocket = serverSocket.accept();System.out.println("客户端连接:" + clientSocket.getInetAddress());// 获取输入流并读取数据BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));String message = reader.readLine(); // 阻塞直到收到消息System.out.println("收到消息:" + message);// 给客户端发送响应PrintWriter writer = new PrintWriter(clientSocket.getOutputStream(), true);writer.println("消息已收到");// 关闭连接clientSocket.close();}}
}
BIO 客户端
package fun.xuewei.nio.network;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;/*** BIO客户端** @author 薛伟*/
public class BioClient {public static void main(String[] args) throws IOException {Socket socket = new Socket("localhost", 8080);System.out.println("连接到服务器...");// 获取输出流并发送数据PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);writer.println("你好,服务器!");// 获取输入流并读取服务器响应BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));String response = reader.readLine();System.out.println("服务器回应: " + response);// 关闭连接socket.close();}
}

NIO 版本:客户端与服务器通信

NIO 模型下,我们使用 SocketChannelServerSocketChannel 来实现客户端与服务器之间的通信,并且可以通过 Selector 来管理多个连接。以下是使用 NIO 实现的客户端与服务器通信的代码。

NIO 服务器端
package fun.xuewei.nio.network;import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;/*** Nio 服务器端** @author 薛伟*/
public class NioServer {public static void main(String[] args) throws IOException {// 创建 Selector 和 ServerSocketChannelSelector selector = Selector.open();ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();serverSocketChannel.configureBlocking(false);// 绑定端口serverSocketChannel.socket().bind(new InetSocketAddress(8080));// 注册到 SelectorserverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);System.out.println("NIO 服务器启动,等待连接...");// 获取字符集,假设文件使用 UTF-8 编码Charset charset = StandardCharsets.UTF_8;while (true) {// 等待事件发生selector.select();// 获取所有已准备就绪的 SelectionKeyIterator<SelectionKey> iterator = selector.selectedKeys().iterator();while (iterator.hasNext()) {SelectionKey key = iterator.next();iterator.remove();// 处理接收客户端连接if (key.isAcceptable()) {ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();SocketChannel clientChannel = serverChannel.accept();clientChannel.configureBlocking(false);// 将客户端连接注册到 SelectorclientChannel.register(selector, SelectionKey.OP_READ);System.out.println("客户端连接:" + clientChannel.getRemoteAddress());}// 处理读取客户端数据if (key.isReadable()) {SocketChannel clientChannel = (SocketChannel) key.channel();ByteBuffer buffer = ByteBuffer.allocate(256);int bytesRead = clientChannel.read(buffer);if (bytesRead == -1) {clientChannel.close();System.out.println("客户端断开连接");} else {buffer.flip();// 将字节缓冲区解码为字符并打印String message = charset.decode(buffer).toString();System.out.println("收到消息:" + message);// 给客户端发送响应buffer.clear();String response = "消息已收到";buffer.put(response.getBytes(charset));  // 使用正确的字符集编码buffer.flip();clientChannel.write(buffer);}}}}}
}
NIO 客户端
package fun.xuewei.nio.network;import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;/*** NIO 客户端** @author 薛伟*/
public class NioClient {public static void main(String[] args) throws IOException {SocketChannel socketChannel = SocketChannel.open();socketChannel.connect(new InetSocketAddress("localhost", 8080));// 获取字符集,假设文件使用 UTF-8 编码Charset charset = StandardCharsets.UTF_8;// 发送消息到服务器ByteBuffer buffer = ByteBuffer.allocate(256);String message = "你好,NIO 服务器!";buffer.put(message.getBytes(charset));  // 使用正确的字符集编码buffer.flip();socketChannel.write(buffer);// 接收服务器响应buffer.clear();socketChannel.read(buffer);buffer.flip();// 将字节缓冲区解码为字符并打印String response = charset.decode(buffer).toString();System.out.println("服务器回应: " + response);// 关闭 SocketChannelsocketChannel.close();}
}
总结
  • 在并发请求数量较少时,BIONIO 性能差距不大。
  • 随着并发请求数增多,BIO 会因为线程过多导致性能下降,而 NIO 通过事件驱动机制,能够较好地处理高并发请求。

实际场景与应用

  • 高并发 Web 服务:NIO 适用于需要处理大量并发连接的场景,例如高并发的 Web 服务器、即时通讯系统、视频流服务等。
  • 大文件传输:NIO 可以高效地处理大文件的读取和写入,避免了传统 I/O 中频繁的阻塞操作。
  • 非阻塞网络服务:如消息队列、数据库连接池等,NIO 提供了一种高效的方式来管理网络连接。

相关文章:

Java NIO基础与实战:如何提升IO操作性能

Java NIO 概述 Java NIO&#xff08;新 I/O&#xff09;是 Java 提供的一个更为高效的 I/O 处理框架。Java NIO&#xff08;New I/O&#xff09;是对传统 I/O&#xff08;java.io&#xff09;模型的改进&#xff0c;它引入了非阻塞 I/O 操作和面向缓冲区的数据读写方式&#x…...

46 map与set

目录 一、序列式容器和关联式容器 二、set系列的使用 &#xff08;一&#xff09;set和mutilset参考文档链接 &#xff08;二&#xff09;set类模板介绍 1、set类声明 2、set的构造和迭代器 3、set的增删查 &#xff08;三&#xff09;multiset类模板 1、multiset和se…...

GPT 系列模型发展史:从 GPT 到 ChatGPT 的演进与技术细节

从 GPT 到 ChatGPT&#xff0c;OpenAI 用短短几年时间&#xff0c;彻底改变了自然语言处理&#xff08;NLP&#xff09;的格局。让我们一起回顾这段激动人心的技术演进史&#xff01;&#x1f680; &#x1f539; GPT&#xff08;2018&#xff09;&#xff1a; 划时代的起点&a…...

RAGFlow和Dify对比

‌ RAGFlow和Dify都是基于大语言模型&#xff08;LLM&#xff09;的应用开发平台&#xff0c;具有相似的功能和应用场景&#xff0c;但它们在技术架构、部署要求和用户体验上存在一些差异。‌‌ RAGFlow和Dify对比 2025-02-13 22.08 RAGFlow‌ ‌技术栈‌&#xff1a;RAGFlow…...

Dart 3.5语法 14-16

017自定代码段让变量有默认值 List下标访问和2种for循环遍历_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1RZ421p7BL?spm_id_from333.788.videopod.episodes&vd_source68aea1c1d33b45ca3285a52d4ef7365f&p42原作者链接&#xff0c;此为修订补充版本 014main…...

yanshee机器人初次使用说明(备注)-PyCharm

准备 需要&#xff1a; 1&#xff0c;&#xff08;优必选&#xff09;yanshee机器人Yanshee 开发者说明 2&#xff0c;手机-联网简单操控 / HDMI线与显示器和键鼠标-图形化开发环境 / 笔记本&#xff08;VNC-内置图形化开发环境/PyCharm等平台&#xff09;。 3&#xff0c;P…...

面试题:如何在10亿个数中判断某个数是否存在?

参考视频 参考视频&#xff1a; 如何用10只老鼠试出藏在99瓶清水中的那瓶毒药 参考视频...

【设计模式】【行为型模式】观察者模式(Observer)

&#x1f44b;hi&#xff0c;我不是一名外包公司的员工&#xff0c;也不会偷吃茶水间的零食&#xff0c;我的梦想是能写高端CRUD &#x1f525; 2025本人正在沉淀中… 博客更新速度 &#x1f44d; 欢迎点赞、收藏、关注&#xff0c;跟上我的更新节奏 &#x1f3b5; 当你的天空突…...

[创业之路-299]:图解金融体系结构

一、金融体系结构 1.1 概述 金融体系结构是一个国家以行政的、法律的形式和运用经济规律确定的金融系统结构&#xff0c;以及构成这个系统的各种类型的银行和非银行金融机构的职能作用和相互关系。以下是对金融体系结构的详细分析&#xff1a; 1、金融体系的构成要素 现代金…...

STM32、GD32驱动TM1640原理图、源码分享

一、原理图分享 二、源码分享 /************************************************* * copyright: * author:Xupeng * date:2024-07-18 * description: **************************************************/ #include "smg.h"#define DBG_TAG "smg&…...

框架ThinkPHP(小迪网络安全笔记~

免责声明&#xff1a;本文章仅用于交流学习&#xff0c;因文章内容而产生的任何违法&未授权行为&#xff0c;与文章作者无关&#xff01;&#xff01;&#xff01; 附&#xff1a;完整笔记目录~ ps&#xff1a;本人小白&#xff0c;笔记均在个人理解基础上整理&#xff0c;…...

09-轮转数组

给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 方法一&#xff1a;使用额外数组 function rotate(nums: number[], k: number): void {const n nums.length;k k % n; // 处理 k 大于数组长度的情况const newNums new A…...

CSV数据列智能合并技术解析

这几天编AI工具信息推荐平台系统&#xff0c;经常遇到数据获取和清洗的问题。今天分享一个将一个csv文件里的列合并到另一个csv文件里。 源码如下&#xff1a; import pandas as pd# 读取源CSV文件 source_file tools_data.csv # 替换为您的源CSV文件路径 data_source pd.…...

Postman如何流畅使用DeepSeek

上次写了一篇文章是用chatBox调用api的方式使用DeepSeek&#xff0c;但是实际只能请求少数几次就不再能给回响应。这回我干脆用最原生的方法Postman调用接口请求好了。 1. 通过下载安装Postman软件 postman下载(https://pan.quark.cn/s/c8d1c7d526f3)&#xff0c;包含7.0和10…...

土星云边缘计算微服务器 SE110S-WA32加持DeepSeek,本地部署企业私有推理大模型!

模型介绍 DeepSeek-R1-Distill-Qwen-7B是一款高性能的语言模型&#xff0c;基于DeepSeek-R1的推理能力&#xff0c;通过蒸馏技术将推理模式迁移到较小的Qwen模型上&#xff0c;在保持高性能的同时&#xff0c;显著降低了资源消耗&#xff0c;更适合在资源受限的环境中部署。 该…...

Linux权限提升-内核溢出

一&#xff1a;Web到Linux-内核溢出Dcow 复现环境&#xff1a;https://www.vulnhub.com/entry/lampiao-1,249/ 1.信息收集&#xff1a;探测⽬标ip及开发端⼝ 2.Web漏洞利⽤&#xff1a; 查找drupal相关漏洞 search drupal # 进⾏漏洞利⽤ use exploit/unix/webapp/drupal_dr…...

【大语言模型】最新ChatGPT、DeepSeek等大语言模型助力高效办公、论文与项目撰写、数据分析、机器学习与深度学习建模等科研应用

ChatGPT、DeepSeek等大语言模型助力科研应用 随着人工智能技术的快速发展&#xff0c;大语言模型如ChatGPT和DeepSeek在科研领域的应用正在为科研人员提供强大的支持。这些模型通过深度学习和大规模语料库训练&#xff0c;能够帮助科研人员高效地筛选文献、生成论文内容、进行数…...

15.Python网络编程:进程池、进程间通信、多线程、进程和线程区别、网络通信、端口、IP地址、socket、UDP、TCP、http

1. 进程池&#xff08;Process Pool&#xff09; 进程池是通过将多个进程放入池中管理来避免频繁地创建和销毁进程&#xff0c;提高效率。Python 提供了 multiprocessing.Pool 类来实现进程池&#xff0c;它可以用于并行计算任务。 示例&#xff1a;使用进程池 from multipr…...

ThinkPHP8视图赋值与渲染

【图书介绍】《ThinkPHP 8高效构建Web应用》-CSDN博客 《2025新书 ThinkPHP 8高效构建Web应用 编程与应用开发丛书 夏磊 清华大学出版社教材书籍 9787302678236 ThinkPHP 8高效构建Web应用》【摘要 书评 试读】- 京东图书 在控制器操作中&#xff0c;使用view函数可以传入视图…...

微信小程序网络请求封装

微信小程序的网络请求为什么要封装&#xff1f;封装使用有什么好处&#xff1f; 封装的目的是为了偷懒&#xff0c;试想一下每次都要wx.request&#xff0c;巴拉巴拉传一堆参数&#xff0c;是不是很麻烦&#xff0c;有些公共的参数例如header&#xff0c;baseUrl是不是可以封装…...

瑞芯微烧写工具

文章目录 前言一、安装驱动二、安装烧写工具1.直接解压压缩包2. 如何使用 三、MASKROM 裸机必备四、LOADER 烧写&#xff0c;前提是搞过第三步没问题五、Update.img包的烧录六、linux下烧写总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 项目需要…...

《Python百炼成仙》21-30章(不定时跟新)

第廿一章 列表开天可变序列初成 不周山的擎天玉柱裂开蛛网纹路&#xff0c;山体内部传出数据结构崩塌的轰鸣。叶军踏着《数据结构真解》残页凌空而立&#xff0c;手中薛香的本命玉尺泛起列表操作的幽光&#xff1a; 补天石序列 [五色石] * 9补天石序列[3] 息壤 # 引发链式变…...

抖音SEO短视频矩阵系统源码:短视频流量密码揭秘

在开发短视频SEO优化排名技术时&#xff0c;仅通过get和set这两个代理无法完全实现目标。实际上&#xff0c;还需要实现has、ownKeys以及getOwnPropertyDescriptor等代理&#xff0c;以更全面地控制私有属性的访问权限。这些代理对于限制对私有属性的访问至关重要。 该技术主要…...

CSS实现与文字长度相同的下划线

可以使用伪元素和一些样式属性来实现与文字长度相同的下划线。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">&…...

【工业安全】-CVE-2022-35561- Tenda W6路由器 栈溢出漏洞

文章目录 1.漏洞描述 2.环境搭建 3.漏洞复现 4.漏洞分析 4.1&#xff1a;代码分析 4.2&#xff1a;流量分析 5.poc代码&#xff1a; 1.漏洞描述 漏洞编号&#xff1a;CVE-2022-35561 漏洞名称&#xff1a;Tenda W6 栈溢出漏洞 威胁等级&#xff1a;高危 漏洞详情&#xff1…...

【GRPO】GRPO原理原文翻译

论文&#xff1a;DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models 注&#xff01;这里我仅仅翻译GRPO部分供学习使用。其他部分请去看原文。 4. 强化学习&#xff08;Reinforcement Learning&#xff09; 4.1. 群组相对策略优化&#xf…...

侯捷 C++ 课程学习笔记:C++ 新标准 11/14 的革新与实战应用

在侯捷老师的 C 系列课程中&#xff0c;《C 新标准 11/14》这门课程让我对现代 C 编程有了全新的认识。C11 和 C14 是 C 语言发展史上的重要里程碑&#xff0c;它们引入了大量新特性&#xff0c;极大地提升了语言的表达能力和开发效率。侯捷老师通过深入浅出的讲解和丰富的实战…...

拉取Openwrt官方源码 编译固件速通

Openwrt 24.10上星期出了&#xff0c;但是恩山没几个人更新&#xff0c;自己编译一个&#xff0c;记录一下方法。 一切从简&#xff0c;不添加任何插件&#xff0c;资源扔恩山了。 【   】红米AX6000 openwrt V24.10.0 uboot大分区固件-小米无线路由器及小米网络设备-恩山无…...

洗牌加速!车规MCU“冷热交加”

汽车芯片赛道&#xff0c;正在经历新一轮震荡期。 本周&#xff0c;全球汽车芯片巨头—NXP对外披露了不及资本市场预期的四季度的财报&#xff0c;营收同比下降9%&#xff0c;全年下降5%&#xff0c;表明工业和汽车市场需求的低迷仍在持续。 公开信息显示&#xff0c;该公司一…...

大模型Deepseek的使用_基于阿里云百炼和Chatbox

目录 前言1. 云服务商2. ChatBox参考 前言 上篇博文中探索了&#xff08;本地&#xff09;部署大语言模型&#xff0c;适合微调、数据高隐私性等场景。随着Deepseek-R1的发布&#xff0c;大语言模型的可及性得到极大提升&#xff0c;应用场景不断增加&#xff0c;对高可用的方…...