二、BIO、NIO、直接内存与零拷贝
一、网络通信编程基础
1、Socket
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,是一组接口,由操作系统提供;
Socket将复杂的TCP/IP协议处理和通信缓存管理都隐藏在接口后面,对用户来说就是使用简单的接口进行网络应用编程;一个客户端连接就会产生一个Socket接口实例与客户端Socket进行通信;

2、短连接
连接→传输数据→关闭连接
传统Http是无状态的,浏览器和服务器进行一次http请求就建立一次连接,任务结束就中断连接;
短连接是指Socket连接后发送后接收完数据马上断开连接;
3、长链接
长链接是指建立Socket后不管是否使用都保持连接;
4、如何选择长链接或者短连接
长链接多用于操作频繁,点对点通信。每个TCP连接都需要三步握手,如果每个操作都是线先连接再操作,会降低处理速度;所以操作完不断开下次直接发送,不用建立连接;例如数据库的连接;但长连接对于服务器来说会消耗一定资源;像web网站一般都是短连接;不过现在的http1.1 尤其是http2、http3开始向长连接演化;
5、网络编程中的通用常识
在通信编程里提供服务的叫服务端,连接服务使用服务的叫客户端,在开发过程中如果类的名字有Server或者ServerSocket的,表示这个类是给服务端容纳网络服务用的;如果类名只包含Socket的,那么表示负责具体的网络读写的;
对于服务端来说ServerSocket就只是个场所;必须绑定某个IP地址,同时还需要监听某个端口;具体和客户端沟通的还是一个一个Socket;
在通信编程中我们只关注三件事:连接、读数据、写数据;我们后面学习的BIO和NIO其实都是处理上面三件事,只是处理方式不同;
二、java原生网络编程-BIO
1、BIO
BIO全为BlockingI/O,阻塞I/O;
在BIO中类ServerSocket负责绑定IP地址,启动监听端口,等待客户连接;客户端Socket类的实力发起连接操作,ServerSocket接收连接后产生一个新的服务端Socket实例负责和客户端通信;

2、BIO阻塞
1、若一个服务器启动就绪,主线程就一直等待客户端连接,此时主线程就一直阻塞;
2、建立连接后,在读取到socket信息之前,线程也一直在等待,一直处于阻塞状态;
3、传统BIO通信模型
采用BIO通信模型的服务端,通常由一个独立的Acceptor线程负责监听客户端的连接,他接收客户端连接请求后为每个客户端创建一个新的线程进行链路处理,处理完成后通过输出流返回应答给客户端,现成销毁。典型的一请求一应答模型,同时数据的读取写入也必须阻塞在一个线程内等待期完成;

缺点:缺乏弹性伸缩能力,当客户端并发访问量增加后,服务端的线程个数和客户端的并发访问数呈1:1的关系,java中线程是比较宝贵的系统资源,线程数量增加,系统性能急剧下降,过多系统就会挂掉;
改进:使用线程池来管理这些线程,这种被称为伪异步I/O模型;

缺点:使用这种模型限制了线程的数量,如果有读取数据缓慢的时候,其它请求就只能一直等待;
三、RPC
1、为什么需要RPC?
传统应用所有功能都写在同一个服务中,服务之间的调用就是我们熟悉的本地方法调用;
随着业务发展,将不同业务放在线程里去做实现异步提升性能,但本质上还是本地方法调用;
随着业务复杂单个应用或单一机器承受不住,我们将核心业务抽取出来独立部署,形成集群,这个时候就需要RPC;
引入RPC框架对我们的代码影响最小,同时可以帮助我们实现架构上的扩展;当服务越来越多,我们RPC之间的调用越来越复杂,此时引入MQ,缓存,同时架构上整体往微服务迁移;
2、什么是RPC?
RPC(Remote Procedure Call-远程过程调用),她是一种通过网络从远程计算机程序上请求服务,而不需要连接底层网络的技术;
3、RPC调用的过程

1、服务消费方以本地调用方式调用client stub(客户端存根(存根就是远程方法在本地的模拟对象));
2 、服务端收到消息后,交给代理存根在服务器的部分后进行解码为实际的方法名和参数;
3、server stub根据解码结果调用本地的实际服务
4、本地服务返回给server stub
5、server stub将返回结果打包成消息并发送给消费方
6、client stub收到消息解码
RPC框架的目标就是将中间步骤都封装起来,让我们远程调用就像调用本地方法一样
4、RPC和HTTP
RPC字面意思是远程调用,是对不同应用间互相调用的一种描述,实现方式可以是最直接的TCP通道,也可以是http;Dubbo是基于tcp通信,gRPC是基于HTTP2.0协议,底层使用到了Netty框架;RPC和HTTP是完全两个不同层级的东西,没有可比性;
5、实现RPC框架的问题
1、代理问题:被调用的服务本质上是远程服务,调用者并不关心,调用者只要结果,具体的事情由代理对象负责。既然是远程代理自然要用代理模式;
2、序列化问题:我们的方法调用,有方法名,方法承诺书这些可能是字符串也可能是类,网络传输中并不认得这些,只认二进制01串,我们需要将这些转换成二进制01串;java提供了Serializable;
3、通信问题:JDK提供了BIO;
四、原生JDK网络编程-NIO
1、什么是NIO?
NIO库是JDK1.4中引入的。NIO弥补了原来BIO的不足,它在标准Java代码中提供了高速的、面向块的I/O。NIO被称为no-blacking io;
2、和BIO的区别
1、面向流和面向缓冲:JavaNIO和IO之间最大的区别是IO面向流,NIO面向缓冲区。面向流意味着每次从流中读取一个或多个字节,没有被缓存在任何地方;不能前后移动流中的数据;如果需要前后移动需要先将它缓存在缓冲区;NIO的缓冲导向方法略有不同,数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区前后移动;增加了灵活性;
2、阻塞与非阻塞IO:java IO的各种流是阻塞的,这意味着当一个线程调用read()或Write()时,该线程呗阻塞,直到有一些数据被读取或数据完全写入,该线程在此期间不能干任何事情;
NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,但它仅能得到目前可用数据,没有可用数据时,就什么都不会获取,而不是包吃线程阻塞,所以该线程可以做其他的事情;非阻塞写也是如此;线程通常将非阻塞IO的空闲时间用于在其它通道上执行IO操作,所以一个线程可以管理多个输入和输出通道;
3、NIO的Reactor模式
“反应”器名字中“反应”的由来;
“反应”即“倒置”,“控制逆转”,具体时间处理器不调用反应器,而向反应器注册一个事件处理器,表示自己对某些事件感兴趣,有事件来了,具体时间处理程序通过时间处理器对某个指定时间发生做出反应;
4、NIO三大组件
NIO有三大核心组件:Selector选择器,Channel管道,buffer缓冲区;
a、Selector(选择器):java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后一个单独的线程来操作这个选择器,选择通道;这使得一个单独的线程很容易管理多个通道;应用程序将向Selector对象注册需要她关注的Channel,以及具体的某一个Channel对哪些IO时间感兴趣。Selector也会维护一个已经注册的Channel的容器;
b、Channels(通道):被建立的一个应用程序和操作系统交互事件、传递内容的渠道;应用程序可以通过通道读取数据,也可以通过通道写数据,而且可以同时读写;
所有被Selector注册的通道,只能是继承了SelectableChannel类的子类。
5 、重要概念
SelectionKey:是一个抽象类,表示SelectbaleChannel在Selector中注册的标识,每个Channel向Selector注册时,都会创建一个SelectionKey。SelectionKey将Channel与Selector简历关系并维护了Channel事件;可以通过Cancel方法取消键,取消的键不会立即从Selector中移除,而是添加到CancelKeys中,在下一次Select操作时移除它,所以调用某个Key时需要使用isValid即兴校验;
SelectionKey类型和就绪条件:在向Selector对象注册感兴趣的事件时,NIO工定义了四种:OP_READ、OP_WRITR、OP_CONNET、OP_ACCEPT,分别对应读写请求连接接收连接等网络Socket操作;
OP_READ:当操作系统读缓冲区有数据可读时就绪。并非时刻都有数据可读,所以一 般需要注册该操作,仅当有就绪时才发起读操作,有的放矢,避免浪费CPU。
OP_WRITR:当操作系统写缓冲区有空闲空间时就绪。一般情况下写缓冲区都有空闲空间,小块数据直接写入即可,没必要注册该操作类型,否则该条件不断就绪浪费CPU;但如果是写密集型的任务,比如文件下载等,缓冲区很可能满,注册该操作类型就很有必要,同时注意写完后取消注册。
OP_CONNET:当SocketChannel.connect()请求连接成功后就绪。该操作只给客户端使用。
OP_ACCEPT:当接收到一个客户端连接请求时就绪。该操作只给服务器使用。
6、服务端和客户端分别感兴趣的类型
ServerSocketChannel和SocketChannel可以注册自己感兴趣的操作类型,当对应操作类型就绪条件满足时OS会通知Channel,
服务器启动ServerSocketChannel关注OP_ACCEPT事件;
客户单启动SocketChannel,连接服务器关注OP_ACCEPT;
服务器接受连接启动一个服务器的SocketChannel ,这个SocketChannel可以关注OP_READ OP_WRITE事件;
7、Buffer的重要属性
capacity:作为一个内存块,Buffer有一个固定的大小值,也叫“capacity”.你只能往里写capacity 个byte、long,char等类型。一旦Buffer满了,需要将其清空(通过读数据或者清除数据)才能继续写数据往里写数据。
position:当你写数据到Buffer中时,position表示当前能写的位置。初始的position值为0.当一个byte、long等数据写到Buffer后,position会向前移动到下一个可插入数据的Buffer单元。position最大可为capacity –1;当读取数据时,也是从某个特定位置读。当将Buffer从写模式切换到读模式,position会被重置为0. 当从Buffer的position处读取数据时,position向前移动到下一个可读的位置。
limit:在写模式下,Buffer的limit表示你最多能往Buffer里写多少数据。写模式下,limit等于Buffer的capacity。当切换Buffer到读模式时,limit表示你最多能读到多少数据。因此,当切换Buffer到读模式时,limit会被设置成写模式下的position值。换句话说,你能读到之前写入的所有数据(limit被设置成已写数据的数量,这个值在写模式下就是position)
8、buffer的分配
想要获得一个bugger对象首先要进行分配。每一个buffer类都有allocate方法;(可以往对上分配,也可以在直接内存分配)
9、直接内存
相关文章:
二、BIO、NIO、直接内存与零拷贝
一、网络通信编程基础 1、Socket Socket是应用层与TCP/IP协议族通信的中间软件抽象层,是一组接口,由操作系统提供; Socket将复杂的TCP/IP协议处理和通信缓存管理都隐藏在接口后面,对用户来说就是使用简单的接口进行网络应用编程…...
生成式AI的发展方向:Chat vs Agent
一、整体介绍 生成式AI作为人工智能领域的重要分支,近年来取得了显著进展,并在多个领域展现出巨大潜力。其核心在于通过机器学习和深度学习算法,从大量数据中学习规律和特征,进而生成具有创新性和多样性的文本、图像、音频和视频…...
吴恩达深度学习笔记:机器学习策略(2)(ML Strategy (2)) 2.9-2.10
目录 第三门课 结构化机器学习项目(Structuring Machine Learning Projects)第二周:机器学习策略(2)(ML Strategy (2))2.9 什么是端到端的深度学习?(What is end-to-end deep learning?&#x…...
变频空调介绍
直流变频空调:只有压缩机是直流变频的,而室外机风电机和室内机风电机都是定频的。 全直流变频空调:它的压缩机是直流变频的,并且室外机风机和室内机风机都是直流变频的。因为大三部件一个不漏,所以就叫做全直流变频。…...
C语言实现二叉树以及二叉树的详细介绍
目录 1.树概念及结构 1.1树的概念 1.2树的相关概念 1.3树的表示 2.二叉树概念及结构 2.1二叉树的概念 2.2特殊的二叉树 2.3二叉树的性质 2.4二叉树的存储结构 3.二叉树顺序结构--特殊的二叉树--堆及其实现 3.1堆的概念及结构 3.2堆的实现 3.2.1堆的结构 3.2.2堆…...
VScode:前端项目中yarn包的安装和使用
一、首先打开PowerShell-管理员身份运行ISE 输入命令: set-ExecutionPolicy RemoteSigned 选择“全是”,表示允许在本地计算机上运行由本地用户创建的脚本,没有报错就行了 二、接着打开VScode集成终端,安装yarn插件 输入 npm ins…...
cmake configure_package_config_file指令详解
在 CMake 中,configure_package_config_file 命令用于生成包配置文件(Package Configuration File),这些文件用于指定如何使用和链接某个库或工具。通常情况下,这些文件用于支持 CMake 的 find_package 命令来查找和加…...
准备跳槽了(仍然底层为主,ue独立游戏为辅)
思考再三,准备跳槽了。 一、跳槽原因: 今年经济形势非常不好。那我为什么还要跳槽呢?因为干不下去了。公司是末位淘汰制,而我绩效垫底了。给我的整改措施中,部门经理让我三个月搞定60个bug,我觉得简直是送…...
汽车免拆诊断案例 | 卡罗拉急加速抖动故障排除
车型信息 2017年改款卡罗拉,排量1.2T,行驶里程48800公里。 故障现象 车辆不管在什么状态下,只要是平缓加速,都不会有抖动。车辆静止时,急加速时,也不会有抖动。但是车速达40公里/小时以上,急加…...
【JAVA】深入理解Hutool中的Pair、Triple和Tuple:组合数据的新方式,方法返回多个值,嘎嘎香,谁用谁知道,比原生好用更强大
Hutool 是一个开源的 Java 工具库,提供了丰富且实用的功能,旨在减少 Java 程序员在日常开发中重复造轮子的工作。在 Hutool 中,Pair、Triple 和 Tuple 是三种用于组合和存储不同数量相关联数据的类。以下是这三个类的简介: 1、添…...
modulepreload 对性能的影响
一、正面影响 减少加载时间: modulepreload 可以让浏览器提前下载模块脚本,减少页面加载时间,特别是对于依赖较多的复杂应用。这种预加载可以让浏览器在遇到 modulepreload 链接时立即开始下载,而不是等到实际需要时才下载提升用…...
问题:向上对齐对象的快捷键是: #学习方法#笔记
问题:向上对齐对象的快捷键是: A、T B、L C、R D、W 参考答案如图所示...
C# 4.List
comboBox使用的下拉框 Lsit 列表 1 创建List对象 List<string> list new List<string>(); 2 Add给list 添加元素 list.Add("吃饭"); list.Add("睡觉"); list.Add("打豆豆"); 3 删除一个元素 list.Remove("吃饭"); // 删…...
界面控件DevExpress Blazor UI v24.1 - 发布全新TreeList组件
DevExpress Blazor UI组件使用了C#为Blazor Server和Blazor WebAssembly创建高影响力的用户体验,这个UI自建库提供了一套全面的原生Blazor UI组件(包括Pivot Grid、调度程序、图表、数据编辑器和报表等)。 DevExpress Blazor控件目前已经升级…...
docker默认存储地址 var/lib/docker 满了,换个存储地址操作流程
1. 查看docker 存储地址 docker info如下 var/lib/docker2、查看内存大小 按需执行 df -h 找超过100M的大文件 find / -type f -size 100M -exec ls -lh {} \; df -Th /var/lib/docker 查找这个文件的容量 df -h 查找所有挂载点 du -hs /home/syy_temp/*1、df -h 2、sud…...
SpringMVC的底层工作原理?
1.用户发送请求至前端控制器DispatcherServlet. 2.DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器 3.HandlerMapping找到具体的处理器(可以根据 xml 配置、注解进行查找),生成处理器及处理器拦截器(如果有则生成)一并返回给DispatcherSe…...
PyTorch 深度学习实践-处理多维特征的输入
视频指路 参考博客笔记 参考笔记二 通过多个线性模型来模拟非线性的空间变换,矩阵计算就是不同维度之间的空间转换 说明:1、乘的权重(w)都一样,加的偏置(b)也一样。b变成矩阵时使用广播机制。神经网络的参数w和b是网络需要学习的,…...
常见逻辑漏洞举例
文章目录 简介用户名可枚举验证码可绕过/验证码回传越权访问任意密码修改验证码回传订单金额任意修改URL跳转漏洞短信轰炸找回密码还有很多逻辑漏洞,其实并没有什么技巧,要分析清楚他的业务逻辑,可能很多正常的流程中就存在着逻辑漏洞。 简介…...
FastAPI 学习之路(五十九)封装统一的json返回处理工具
在本篇文章之前的接口,我们每个接口异常返回的数据格式都不一样,处理起来也没有那么方便,因此我们可以封装一个统一的json。 from fastapi import status from fastapi.responses import JSONResponse, Response from typing import Unionde…...
tg小程序前端-dogs前端源码分析
tg小程序前端-dogs前端源码分析 前端源码 index.html <!DOCTYPE html> <html lang="en"><head><script src="https://telegram.org/js/telegram-web-app.js" onload="window.Telegram.WebApp.expand(); window.Telegram.WebA…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
