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

网络编程(一):服务器模型、Java I/O模型、Reactor事件处理模型、I/O复用

文章目录

  • 一、Socket和TCP/IP协议族的关系
  • 二、服务器模型
    • 1.C/S模型(Client/Server Model)
    • 2.P2P模型(Peer-to-Peer Model)
  • 三、Java的I/O演进
    • 1.BIO(阻塞)
      • (1)工作流程
      • (2)代码实现
    • 2.NIO(多路复用/轮询)
      • (1)工作流程
      • (2)代码实现
    • 3.NIO2.0——AIO(异步/事件驱动)
  • 四、并发事件处理模式
    • 1.Reactor模式(NIO)
      • (1)单Reactor单线程模型
      • (2)单Reactor多线程模型(Redis)
      • (3)主从Reactor多线程模型(Netty)
    • 2.Proactor模式(AIO)
  • 五、I/O复用

一、Socket和TCP/IP协议族的关系

Socket和TCP/IP协议族是网络编程中的两个重要概念,它们之间存在密切的关系。

首先,TCP/IP协议族是一组用于互联网通信的网络协议的集合。它由多个协议组成,其中最核心的协议是TCP(Transmission Control Protocol)和IP(Internet Protocol)。TCP协议提供可靠的数据传输和连接管理,而IP协议则负责将数据包从源地址传输到目的地址。

Socket是一种抽象概念,它提供了应用程序与网络之间的接口。通过Socket,应用程序可以通过网络与其他应用程序进行通信。在编程语言中,Socket通常被封装成库或API,以提供方便的网络编程接口。

TCP/IP协议族中的TCP协议使用Socket来实现端到端的数据传输。在TCP/IP网络中,每个主机都有一个唯一的IP地址,而每个运行TCP协议的应用程序都使用一个Socket来标识自己。一个Socket由IP地址和端口号组成,用于唯一标识网络中的一个应用程序。

当应用程序使用Socket进行网络通信时,它可以创建一个Socket对象,并指定目标主机的IP地址和端口号。通过Socket对象,应用程序可以使用TCP协议建立与目标主机的连接,并进行数据的发送和接收。TCP协议负责将数据分割成小的数据包,并通过IP协议将这些数据包从源主机传输到目的主机。

总结来说,Socket是应用程序与网络之间的接口,而TCP/IP协议族则是网络通信的基础协议。通过Socket和TCP协议,应用程序可以在TCP/IP网络中进行可靠的数据传输和通信。

二、服务器模型

服务器模型是指在网络中进行通信和资源共享时所采用的不同架构模式。常见的服务器模型包括C/S模型(Client/Server Model)和P2P模型(Peer-to-Peer Model)。

1.C/S模型(Client/Server Model)

C/S模型是一种常见的服务器模型,其中客户端(Client)和服务器(Server)之间存在明确的角色和功能分工。

  • 客户端:客户端是发起请求的一方,它向服务器发送请求并接收服务器的响应。客户端通常是一台终端设备,如个人计算机、智能手机等。
  • 服务器:服务器是提供服务的一方,它接收客户端的请求并提供相应的服务或资源。服务器通常是一台高性能的计算机或设备,具备处理请求和提供服务的能力。

在C/S模型中,客户端和服务器之间通过网络进行通信。客户端发起请求,服务器接收请求并处理,然后将响应发送回客户端。这种模型可以实现中心化的控制和管理,服务器负责处理和存储数据,客户端主要负责用户界面的展示和交互。

2.P2P模型(Peer-to-Peer Model)

P2P模型是一种去中心化的服务器模型,其中参与通信的设备之间平等地协作,没有明确的客户端和服务器的区别。

  • 对等节点:在P2P模型中,所有参与通信的设备都是对等节点,它们既是服务的提供者,也是服务的请求者。每个节点都可以与其他节点直接通信,共享资源或提供服务。

在P2P模型中,设备之间通过直接连接进行通信,而不依赖于中央服务器。每个设备既可以发起请求,也可以响应其他设备的请求,实现了资源和服务的共享。P2P模型常用于文件共享、实时通信等场景,例如BitTorrent协议就是一种典型的P2P协议。

总结来说,C/S模型是一种中心化的服务器模型,客户端和服务器之间存在明确的角色和功能分工;而P2P模型是一种去中心化的服务器模型,参与通信的设备平等地协作,共享资源和服务。选择适合的服务器模型取决于具体的应用需求和网络架构。

三、Java的I/O演进

1.BIO(阻塞)

网络编程的基本模型是Client/Server模型,也就是两个进程之间进行相互通信,其中服务端提供位置信息(绑定的IP地址和监听端口),客户端通过连接操作向服务端监听的地址发起连接请求,通过三次握手建立连接,如果连接建立成功,双方就可以通过网络套接字(Socket)进行通信。

在基于传统同步阻塞模型开发中,ServerSocket负责绑定IP地址,启动监听端口;Socket负责发起连接操作。连接成功之后,双方通过输入和输出流进行同步阻塞式通信。

BIO,即Blocking IO,阻塞型I/O。阻塞体现在两个地方,连接线程的阻塞和读写的阻塞。

(1)工作流程

服务端启动ServerSocket;
客户端启动 Socket 对服务器进行通信,服务端对每个客户端建立一个线程与之通讯(可以使用线程池进行优化);
客户端发出请求后,先咨询服务器是否有线程响应,如果没有则会等待(即阻塞);
如果有响应,客户端线程会等待请求结束后,再继续执行。

在这里插入图片描述

(2)代码实现

  • 服务端:
package bio;import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;public class BIOServer {//创建一个线程池,用于处理客户端连接后的工作public static ThreadPoolExecutor pool=new ThreadPoolExecutor(10, 10, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<>());public static void main(String[] args) throws IOException{ServerSocket serverSocket=new ServerSocket(8888);while(true){//1 等待客户端连接是阻塞的Socket socket=serverSocket.accept();System.out.println("客户端连接上了");//2 连接上以后向线程池提交一个任务用于处理连接pool.execute(new Runnable() {@Overridepublic void run() {while(true){try{//读写也是阻塞的//创建输出流,server向client输出PrintStream printStream = new PrintStream(socket.getOutputStream());printStream.println("message from server 8888");printStream.close();socket.close();}catch(IOException e){e.printStackTrace();}}}});}}
}
  • 客户端:
package bio;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;public class BIOClient {public static void main(String[] args) throws IOException{Socket socket = new Socket("127.0.0.1", 8888);BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));System.out.println("This message comes from server:"+bufferedReader.readLine());bufferedReader.close();socket.close();}
}

在这里插入图片描述

  • 缺点:
    • accept()等待客户端连接是阻塞的,有时候需要进行无谓的等待,效率低下,浪费资源。
    • 引入线程池进行优化提升了高并发能力,即能够同时处理多个客户端请求了,但是却带来了一个问题,随着开启的线程数目增多,将会消耗过多的内存资源,导致服务器变慢甚至崩溃。
    • 读写操作仍然是阻塞的,如果客户端半天没有操作,也会浪费资源,因此效率不高。

2.NIO(多路复用/轮询)

NIO,即non-blocking lO,非阻塞型IO。

  • 非阻塞——减少线程资源的浪费:
    BIO提供非阻塞读写模式,使一个线程从某通道发送请求或者读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取,而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。非阻塞写也是如此,一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。可以做到 用一个线程来处理多个操作,体现了一种多路复用的思想。 而不是像BIO那样,一个连接过来就得分配一个线程,造成资源的浪费。

  • 处理数据的方式:
    BIO 以流的方式处理数据,而 NIO 以缓冲区(也被叫做块)的方式处理数据,块 IO 效率比流 IO 效率高很多。BIO 基于字符流或者字节流进行操作,而 NIO 基于 Channel 和 Buffer 进行操作,数据总是从通道读取到缓冲区或者从缓冲区写入到通道。

  • 复用:
    Selector(选择器)用于监听多个通道的事件(比如连接请求,数据到达等),因此使用单个线程就可以监听多个客户端通道。

(1)工作流程

Channel(通道),Buffer(缓冲区), Selector(选择器)为NIO的三大核心组件。

  • Channel(通道):
    相比于BIO流的读写,Channel的读写是双向的,既可以从通道中读取数据,又可以写数据到通道。通道可以非阻塞读取和写入通道/缓冲区,也支持异步地读写。

  • Buffer(缓冲区):
    在客户端和Channel之间,增加Buffer缓冲区的支持,更加容易操作和管理。

  • Selector(选择器):
    用来 轮询 检查一个或多个NIO通道,并确定哪些通道已经准备好进行读取或写入。这样,一个单独的线程可以管理多个channel,从而管理多个网络连接,提高效率。

在这里插入图片描述

(2)代码实现

代码来自:here

  • 服务端:
package nio;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.util.Iterator;
import java.util.Set;public class NIOServer {public static void main(String[] args) throws IOException {// 创建ServerSocketChannelServerSocketChannel serverSocketChannel = ServerSocketChannel.open();// 创建一个Selector对象,Selector selector = Selector.open();// 绑定端口6666, 在服务器端监听serverSocketChannel.socket().bind(new InetSocketAddress(6666));// 设置为非阻塞serverSocketChannel.configureBlocking(false);// 把serverSocketChannel注册到selectorserverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);// 循环等待用户连接while (true){if (selector.select(1000) == 0){ //等待(阻塞)一秒, 没有事件发生
//            if (selector.selectNow() == 0){ // 也可以设置成非阻塞的System.out.println("服务器等待了一秒,无连接");continue;}// 如果返回的>0 , 说明客户端有了动作,就获取相关的selectionKey集合Set<SelectionKey> selectionKeys = selector.selectedKeys(); // 返回关注事件的集合// 遍历selectionKeysIterator<SelectionKey> keyIterator = selectionKeys.iterator();while (keyIterator.hasNext()){// 获取到selectionKeySelectionKey key = keyIterator.next();//根据key对应的通道获取事件并做相应处理if (key.isAcceptable()){//如果是OP_ACCEPT, 表示有新的客户端产生//给该客户端生成SocketChannelSocketChannel socketChannel = serverSocketChannel.accept();//将socketChannnel设置为非阻塞socketChannel.configureBlocking(false);//将socketChannel注册到selector上, 设置事件为OP_READ,同时给socketChannel关联一个buffersocketChannel.register(selector,SelectionKey.OP_READ, ByteBuffer.allocate(1024));}if (key.isReadable()){// 发生了OP_READSocketChannel channel=(SocketChannel)key.channel();ByteBuffer buffer = (ByteBuffer)key.attachment();channel.read(buffer);System.out.println("from 客户端"+new String(buffer.array()));}// 手动从集合中移除当前的selectionKey, 防止多线程情况下的重复操作keyIterator.remove();}}}
}
  • 客户端:
package nio;import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;public class NIOClient {public static void main(String[] args) throws IOException {// 获取一个网络通道SocketChannel socketChannel = SocketChannel.open();// 设置为非阻塞socketChannel.configureBlocking(false);//设置服务器端ip和端口InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 6666);if (!socketChannel.connect(inetSocketAddress)){while (!socketChannel.finishConnect()){//如果没有连接成功,客户端是非阻塞的,可以做其它工作System.out.println("等待连接...");}}// 如果连接成功,就发送数据String str = "hello world";ByteBuffer buffer = ByteBuffer.wrap(str.getBytes());// 发送数据 , 将buffer中的数据写入到channel中socketChannel.write(buffer);System.in.read();}}

在这里插入图片描述

3.NIO2.0——AIO(异步/事件驱动)

AIO,即Asynchronous I/O,异步非阻塞IO。AIO提供的最大的特点是具备异步功能,采用“订阅-通知”模式,即应用程序向操作系统注册IO监听,然后继续做自己的事情。当操作系统发生IO事件,并且准备好数据后,在主动通知应用程序,触发相应的函数。

在这里插入图片描述

下面是一段简单的代码示例:

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.Future;public class NIO2AsyncFileIOExample {public static void main(String[] args) {try {// 通过路径获取文件通道Path path = Paths.get("test.txt");AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ, StandardOpenOption.WRITE);// 分配缓冲区ByteBuffer buffer = ByteBuffer.allocate(1024);// 异步读取文件Future<Integer> readResult = fileChannel.read(buffer, 0);while (!readResult.isDone()) {// 在等待异步读取完成时可以进行其他操作System.out.println("Waiting for read operation to complete...");}// 打印读取结果buffer.flip();System.out.println("Read data: ");while (buffer.hasRemaining()) {System.out.print((char) buffer.get());}System.out.println();// 异步写入数据String newData = "Hello, NIO 2.0!";buffer.clear();buffer.put(newData.getBytes());buffer.flip();Future<Integer> writeResult = fileChannel.write(buffer, 0);while (!writeResult.isDone()) {// 在等待异步写入完成时可以进行其他操作System.out.println("Waiting for write operation to complete...");}System.out.println("Data written to file.");// 关闭文件通道fileChannel.close();} catch (IOException e) {e.printStackTrace();}}
}

四、并发事件处理模式

1.Reactor模式(NIO)

使用 Java NIO 构建的 IO 程序,它的工作模式是:主动轮训 IO 事件,IO 事件发生后程序的线程主动处理 IO 工作,这种模式也叫做 Reactor 模式。

(1)单Reactor单线程模型

只有一个线程来执行所有的任务,效率低下,并且也有可靠性问题。

在这里插入图片描述

(2)单Reactor多线程模型(Redis)

相比于上一个模型,增加了线程池的支持,从一定程度上提升了并发效率,但是引入线程池可能会涉及到数据同步问题。Redis底层就是基于这种模型。

在这里插入图片描述

(3)主从Reactor多线程模型(Netty)

在上一个模型的基础上,一个Reactor变成了两个,主Reactor创建连接,从Reactor分发读写任务,能支持更高的并发量。Netty是基于这种模型。
在这里插入图片描述

2.Proactor模式(AIO)

使用 Java AIO 构建的 IO 程序,它的工作模式是:将 IO 事件的处理托管给操作系统,操作系统完成 IO 工作之后会通知程序的线程去处理后面的工作,这种模式也叫做 Proactor 模式。

现在AIO和Proactor使用还不怎么广泛。

五、I/O复用

select、poll、epoll

相关文章:

网络编程(一):服务器模型、Java I/O模型、Reactor事件处理模型、I/O复用

文章目录 一、Socket和TCP/IP协议族的关系二、服务器模型1.C/S模型&#xff08;Client/Server Model&#xff09;2.P2P模型&#xff08;Peer-to-Peer Model&#xff09; 三、Java的I/O演进1.BIO&#xff08;阻塞&#xff09;&#xff08;1&#xff09;工作流程&#xff08;2&am…...

flyway适配高斯数据库

文章目录 flyway适配高斯数据库 flyway适配高斯数据库 flyway-core 源码版本&#xff1a;6.2.2 tag 由于高斯和postgresql使用的驱动都是一样的&#xff0c;所以基于flyway支持已有的postgresql数据库来改造 修改点如下&#xff1a; 1、PostgreSQLConnection 类中的 doRest…...

LVS keepalived实现高可用负载群集

目录 1 Keepalived及其工作原理 1.1 Keepalived体系主要模块及其作用&#xff1a; 2 LVSKeepalived 高可用群集部署 2.1 配置负载调度器&#xff08;主、备相同&#xff09; 2.1.1 配置keeplived&#xff08;主、备DR 服务器上都要设置&#xff09; 2.1.2 启动 ipvsadm 服…...

HTTP RESTFul RPC

一、简介 &#xff08;1&#xff09;HTTP&#xff08;Hypertext Transfer Protocol&#xff09;是一种应用层协议。它经常用于在Web和服务器之间通讯&#xff0c;或服务与服务之间通讯。 &#xff08;2&#xff09;RESTFul 约束HTTP协议实现上的规范设计。 &#xff08;3&am…...

短视频seo矩阵系统源码开发搭建--代用户发布视频能力

短视频SEO矩阵系统源码开发搭建的代用户发布视频能力&#xff0c;主要是指在系统平台上&#xff0c;允许用户将其创作的内容发布到指定的账号或平台&#xff0c;并设置好相关的标题、话题、锚点等信息。 一、搭建步骤及注意事项 确定使用场景。根据业务需求&#xff0c;确定该…...

真实的产品开发中,后端的设计规约可以写哪些

真实的产品开发中&#xff0c;后端的设计规约可以写哪些 产品开发的后端设计规约通常包括以下内容&#xff1a; 数据模型设计&#xff1a;详细描述数据库的结构&#xff0c;包括数据表的设计、字段的定义和关系的设置等。 业务逻辑设计&#xff1a;详细描述后端的业务逻辑&a…...

Pytorch 多卡并行(2)—— 使用 torchrun 进行容错处理

前文 Pytorch 多卡并行&#xff08;1&#xff09;—— 原理简介和 DDP 并行实践 介绍了使用 Pytorch 的 DDP 库进行单机多卡训练的方法&#xff0c;本文进一步说明如何用 torchrun 改写前文代码&#xff0c;以提高模型训练的效率和容错性torchrun 是从 Pytorch 1.9.0 开始引入的…...

Java异常处理(详解)

Java异常处理 前言一、异常与异常类1.异常的概念2.异常类Error类Exception类&#xff08;1&#xff09;非检查异常&#xff08;2&#xff09;检查异常 二、异常处理1.异常的抛出与捕获2.try-catch-finally语句3.声明方法抛出异常3.用throw 语句抛出异常 三、自定义异常类 前言 …...

嵌入式-数据进制之间的转换

目录 一.简介 1.1十进制 1.2二进制 1.3八进制 1.4十六进制 二.进制转换 2.1二进制-十进制转换 2.2八进制-十进制转换 2.3十六进制-十进制转换 2.4十进制-二进制转换 2.5十进制-八进制转换 2.6十进制-十六进制转换 2.7小数部分转换 一.简介 被传入到计算机的数据要…...

腾讯mini项目-【指标监控服务重构】2023-08-20

今日已办 PPT制作 答辩流程 概述&#xff1a;对项目背景、架构进行介绍&#xff08;体现我们分组的区别和需求&#xff09;人员&#xff1a;小组成员进行简短的自我介绍和在项目中的定位&#xff0c;分工进展&#xff1a;对项目进展介绍&#xff0c;其中a、b两组的区别和工作…...

智能文本纠错API的应用与工作原理解析

引言 在数字时代&#xff0c;文本撰写和传播变得日益重要&#xff0c;无论是在学校里写论文、在职场中发送邮件&#xff0c;还是在社交媒体上发表观点。然而&#xff0c;文字错误、标点符号错误、语法问题和不当的表达常常会削弱文本的质量&#xff0c;降低信息传达的效果。为…...

在springboot下将mybatis升级为mybatis-plus

在springboot下将mybatis升级为mybatis-plus 1. 整体描述2. 具体步骤2.1 更新pom引用2.2 更新yml配置2.3 更新config配置2.4 BaseEntity修改 3. 程序启动4. 总结 1. 整体描述 之前项目工程用的是mybatis&#xff0c;现在需要将其替换为mybatis-plus&#xff0c;mybatis-plus的…...

Vuex详解:Vue.js的状态管理方案

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…...

栈与队列经典题目——用队列实现栈

本篇文章讲解栈和队列这一部分知识点的经典题目&#xff1a;用栈实现队列、用队列实现栈。对应的题号分别为&#xff1a;Leetcode.225——用队列实现栈&#xff0c;。 在对两个题目进行解释之前&#xff0c;先回顾以下栈和队列的特点与不同&#xff1a; 栈是一种特殊的线性表…...

Python stomp 发送消息无法显示文本

我们向消息服务器通过 stomp 发送的是文本消息。 当消息服务器发送成功后&#xff0c;消息服务器上的文本没有显示&#xff0c;显示的是 2 进制的数据。 如上图&#xff0c;消息没有作为文本来显示。 问题和解决 消息服务器是如何判断发送的小时是文本还是二进制的。 根据官…...

postgresql-视图

postgresql-视图 视图概述使用视图的好处 创建视图修改视图删除视图递归视图可更新视图WITH CHECK OPTION 视图概述 视图&#xff08;View&#xff09;本质上是一个存储在数据库中的查询语句。视图本身不包含数据&#xff0c;也被称为 虚拟表。我们在创建视图时给它指定了一个…...

科技资讯|Vision Pro头显无损音频仅限USB-C AirPods Pro 2耳机

彭博社的马克・古尔曼在最新发布的推文中表示&#xff0c;苹果 Vision Pro 头显的无损音频仅限于 USB-C AirPods Pro 2 耳机。 新款采用 USB-C 的 AirPods Pro 2 升级到了 IP54 级别&#xff08;原版不防尘&#xff0c;仅 IPX4 级抗水&#xff09;&#xff0c;可陪伴用户在恶劣…...

Postman应用——初步了解postman

Postman 是一个用于构建和使用 API 的 API 平台&#xff0c;Postman 简化了 API 生命周期的每个步骤并简化了协作&#xff0c;可以更快地创建更好的 API。 Postman 包含一个基于Node.js的强大的运行时&#xff0c;允许您向请求&#xff08;request&#xff09;和分组&#xff…...

分析报告显示,PHP是编程语言主力军,且在电商领域占据“统治地位”

日前有有业内专家透露了PHP语言的使用数据&#xff0c;并强调了PHP语言对于互联网的作用。 而根据W3 Techs发布的《全球前1000万个网站使用的编程语言分析(截至 2023.8)》中&#xff0c;有这样一组数据引起广泛的关注。PHP占比 77.2%、ASP占比 6.9%、Ruby 占比5.4%。 此外&am…...

关于Greenplum Platform Extension Framework(PXF)

本文翻译自 https://docs.vmware.com/en/VMware-Greenplum-Platform-Extension-Framework/6.6/greenplum-platform-extension-framework/overview_pxf.html 随着数据存储和云服务的爆炸式增长&#xff0c;数据现在以各种格式驻留在许多不同的系统中。通常&#xff0c;数据根据…...

编程获取图像中的圆半径

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 即将推出EmguCV的教程&#xff0c;请大家还稍作等待。 之前网友咨询如何获得图像中圆形的半径&#xff0c;其中有两个十字作为标定…...

什么是Scrum?如何实施Scrum(敏捷开发)以及敏捷工具

​ 什么是Scrum&#xff1f; Scrum是一个敏捷开发框架&#xff0c;它是一个增量的、迭代的开发过程。它被广泛应用于敏捷软件开发&#xff0c;在Scrum中&#xff0c;开发过程由若干个短的迭代周期组成&#xff0c;每个迭代周期称为一个Sprint。 那么Scrum如何实施呢&#xf…...

提升运营效率:仓储可视化的实时监控与优化

当今&#xff0c;仓储管理已经不再是简单的储存和分发商品的过程。随着供应链的复杂性增加&#xff0c;企业需要更高效的方式来管理和优化其仓储运营。在这个背景下&#xff0c;仓储可视化成为了一项关键的技术&#xff0c;它利用先进的数字化工具和数据分析来提升仓储管理的效…...

代理模式和单一职责原理一文读懂(设计模式与开发实践 P6)

文章目录 代理模式实现保护代理虚拟代理单一职责原理代理和本体 - 接口一致性虚拟代理 - 合并请求缓存代理其他代理 代理模式 定义&#xff1a;为一个对象提供一个代用品 & 占位符&#xff0c;以便 控制对他的访问 关键&#xff1a;不方便直接访问某个对象或不满足需要的时…...

Linux网络编程|TCP编程

一.网络基础 1.1网络发展史 Internet&#xff0d;“冷战”的产物 1957年10月和11月&#xff0c;前苏联先后有两颗“Sputnik”卫星上天 1958年美国总统艾森豪威尔向美国国会提出建立DARPA (Defense Advanced Research Project Agency)&#xff0c;即国防部高级研究计划署&#…...

FPGA----VCU128的DDR4无法使用问题(全网唯一)

1、在Vivado 2019.1版本中使用DDR4的IP核会遇到如下图所示的错误&#xff0c;即便过了implementation生成了bit&#xff0c;DDR4也无法正常启动。 2、解决办法&#xff0c;上xilinx社区搜一下就知道了 AMD Customer Communityhttps://support.xilinx.com/s/article/69035?lan…...

【毕设选题】flink大数据淘宝用户行为数据实时分析与可视化

文章目录 0 前言1、环境准备1.1 flink 下载相关 jar 包1.2 生成 kafka 数据1.3 开发前的三个小 tip 2、flink-sql 客户端编写运行 sql2.1 创建 kafka 数据源表2.2 指标统计&#xff1a;每小时成交量2.2.1 创建 es 结果表&#xff0c; 存放每小时的成交量2.2.2 执行 sql &#x…...

机器学习练习-决策树

机器学习练习-决策树 代码更新地址&#xff1a;https://github.com/fengdu78/WZU-machine-learning-course 代码修改并注释&#xff1a;黄海广&#xff0c;haiguang2000wzu.edu.cn 1&#xff0e;分类决策树模型是表示基于特征对实例进行分类的树形结构。决策树可以转换成一个if…...

分类预测 | Matlab实现基于LFDA-SVM局部费歇尔判别数据降维结合支持向量机的多输入分类预测

分类预测 | Matlab实现基于LFDA-SVM局部费歇尔判别数据降维结合支持向量机的多输入分类预测 目录 分类预测 | Matlab实现基于LFDA-SVM局部费歇尔判别数据降维结合支持向量机的多输入分类预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 基于局部费歇尔判别数据降维的L…...

Say0l的安全开发-代理扫描工具-Sayo-proxyscan【红队工具】

写在前面 终于终于&#xff0c;安全开发也练习一年半了&#xff0c;有时间完善一下项目&#xff0c;写写中间踩过的坑。 安全开发的系列全部都会上传至github&#xff0c;欢迎使用和star。 工具链接地址 https://github.com/SAY0l/Sayo-proxyscan 工具简介 SOCKS4/SOCKS4…...

安徽政府网站建设/百度竞价推广点击软件

经典面试题&#xff1a;链表的相交与环问题 点击打开链接 http://blog.csdn.net/hackbuteer1/article/details/7583102 c语言面试精华版 点击打开链接 http://blog.csdn.net/hackbuteer1/article/details/6550824...

网站开发文件夹/合肥网络推广服务

计算机应用基础第一章笔记1.计算机工具的变迁2.计算机的发展过程3.冯.诺依曼计算机的工作原理4.计算机系统的硬件和软件组成5.计算机的性能指标6.影响计算机的性能因素7.数据在计算机中表示和存储方式8.数制之间的转换冯.诺依曼体系的结构计算机软件的类别计算机的性能指标二进…...

淄博网站建设淄博/职业技术培训机构

链式编程 多行代码合并成一行代码,前提要认清此行代码返回的是不是对象.是对象才能进行链式编程 .html(‘val’).text(‘val’).css()链式编程&#xff0c;隐式迭代 链式编程注意&#xff1a;$(‘div’).html(‘设置值’).val(‘设置值’);这样可以&#xff0c;但是$(‘div’).…...

网站设计费用志/网络营销的几种模式

域名泛解析什么意思 在域名前添加任何子域名&#xff0c;均可访问到所指向的网站。也就是客户的域名yfi6.com之下所设的*.yfi6.com全部域名均可访问。 域名泛解析怎么设置 泛域名解析是指将*.域名解析到同一IP。 泛域名解析和域名解析有何不同&#xff1f; 泛域名解析是指&a…...

四川酒店网站建设/网站收录查询网

我会通过本系列文章&#xff0c;详细介绍如何从零开始用51单片机去实现智能小车的控制&#xff0c;在本系列的上一篇文章中介绍了如何让小车实现自动避障&#xff0c;本文作为本系列的第四篇文章&#xff0c;主要介绍蓝牙模块的使用&#xff0c;如何通过蓝牙进行数据传输&#…...

网站建设常见问题解决方案/首页优化排名

Linux下察看swap分区大小的命令   top   或者fdisk -l   或者free -m   SWAP分区一般大小为物理内存的2倍&#xff0c;但最大不超过2G&#xff1b;   增加SWAP空间的方法有两个&#xff1a;增加另外一个SWAP分区&#xff0c;或通过创建一个SWAP文件来实现。   一&a…...