浅谈网络通信(2)

news2024/12/27 14:26:41

文章目录

  • 一、TCP
    • 1.1、TCP提供的api —— ServerSocket 、Socket
    • 1.2、使用TCP协议编写回显服务器
    • 1.3、长/短连接
  • 二、应用层协议、传输层协议详解
    • 2.1、应用层(后端开发必知必会)
      • 2.1.1、自定义应用层协议
      • 2.1.2、通用的协议格式
        • 2.1.2.1、XML
        • 2.1.2.2、json
        • 2.1.2.3、protobuffer
    • 2.2、传输层
      • 2.2.1、UDP

一、TCP

TCP服务器端需要做的事:
1、获取连接
2、处理连接:(1)、读取请求并解析 (2)、根据请求计算出响应 (3)、写回响应
TCP客户端需要做的事:
1、构造请求并发送
2、从服务器端获取响应
3、把响应显示

1.1、TCP提供的api —— ServerSocket 、Socket

1、ServerSocket:
ServerSocket 是提供给服务器使用的类。
由于TCP特点是有连接的,因此TCP服务器启动后的第一件事不是读取客户端请求,而是先处理客户端的 “连接”。

握手是由系统内核负责的,写代码过程中无法感知到握手的过程,写代码时主要是处理连接,连接是握手之后得到的东西,是比较抽象的,就是说客户端和服务器彼此保存了对方的信息,这个抽象的连接是由系统内核完成的)。

一个服务器要对应很多的客户端,因此内核中的连接很多,这些连接就像一个一个的待办事项,这些待办事项存储在一个队列这样的数据结构中,应用程序就需要从队列中一个一个的取出连接,完成这些连接任务。

2、Socket:
既会给服务器使用,也会给客户端使用。

TCP传输数据的基本单位是 字节流,一个TCP数据报,就是一个字节数组 byte[] buf。

1.2、使用TCP协议编写回显服务器

使用TCP协议编写回显服务器的源码地址
代码详解:
1、serverSocket.accept():把内核中的连接获取到应用程序中。(但是此处的返回值并非是一个 “Connection” 这样的对象,而是一个 Socket 对象,这个 Socket 对象,就像一个耳麦一样,拿着它既可以讲话让对方听见,也可以听到对方讲话的声音(是TCP全双工的表现))。
这个过程类似于 “生产者消费者模型”。

在这里插入图片描述
但有可能出现一种情况:即当程序执行到代码serverSocket.accept()时,有可能此时服务器还没有客户端连接,那么此时队列中也就没有任何连接,应用程序也就从内核中取不到任何连接,此时程序就会阻塞在accept()方法这里,直到有客户端连接成功为止。(一次IO分两个部分:1、等待(阻塞)。2、拷贝数据)

为啥建立连接要进行握手??就像相亲时不可能双方一见面就马上结婚(结婚也是一种抽象的连接),必须有一个相互了解的阶段。此处衍生出一个重要的面试题:TCP的3次握手和14次挥手。(后面再详解)

2、在TCP服务器代码处,有两种 Socket 对象,一种是 ServerSocket ,一种是 Socket 。
在这里插入图片描述
那这两种 Socket 有什么区别?
serverSocket 就像面包店外试吃区的销售人员,socket 就像面包店里售卖面包的销售人员。试吃区的销售人员其实就是在为面包店拉客,面包店里的销售人员会给被试吃区拉来的顾客详细介绍店里的面包种类,来进一步吸引顾客购买。这两种销售人员虽然有不一样的称呼,但是他们的目的都是为了销售面包店里的面包给顾客。

ServerSocket 只有一个,生命周期跟随程序,不关闭也没事。但是对于 Socket 来说,一定要关闭。如果有1w个客户端连接,就会有1w个Socket,此处的 Socket 是被反复创建的,因此对于 Socket 来说,必须确保连接断开之后会被关闭!否则就会发生文件资源泄露,导致整个程序被带走。

3、在TCP服务器代码中,通过方法 processConnection() 处理客户端的一个连接,由于accept() 方法会阻塞,因此需要借助线程池来处理客户端的连接。当只有一个执行流时,accept()方法处发送阻塞会导致其他连接了服务器的客户端没办法继续执行,这显然不符合一个服务器的执行常理,因此服务器端需要借助线程池的多个执行流处理客户端的连接。

在这里插入图片描述
其实我们的服务器代码没加上线程池前,会出现一个问题:当第一个客户端连接好了之后,第二个客户端,不能正确被处理:即此时服务器看不到客户端上线,同时客户端发来的请求也无法被处理。当第一个客户端退出之后,之前第二个客户端发来的请求,就能正确的响应了。

在这里插入图片描述
但是对于服务器来说,服务器是能够同时处理多个客户端的请求,因此上述第一个客户端连接执行完毕后,第二个客户端连接才能被处理这种做法是不正常的,因为一个客户端连接不知道什么时候才能执行完,一个客户端连接是可以进行很多个请求、响应的,因此对应的也就不知道accept()方法的阻塞什么时候才能结束,因此想要解决accept()的阻塞,可以使用线程池来解决该问题,使用线程池后程序中就可以含有多个执行流,既可以执行accept(),也可以执行processConnection()方法。一个执行流执行processConnection()方法,另一个执行流也能快速调用到accept()。不使用线程池也可以,只要是多线程方式都可以解决该问题。(在网络编程中,多线程会常常使用到)

还有一个问题
有些同学可能会在TCP服务器端写出这样的代码:
在这里插入图片描述

还有问题:我们引入了 线程池 解决了 accept() 阻塞问题,但是线程池也是有开销的,在服务器对应的客户端很多的情况下,服务器就需要创建出大量的线程去处理客户端连接的任务,此时服务器的开销是很大的,响应速度也会大打折扣。那么是否有办法,使用一个线程或者3、4个线程就能让服务器高效的处理客户端的并发(几万/几十万客户端)请求?

其实随着互联网的发展,客户端会越来愈多,请求也越来越多,C10M就出现了。C10M:同一时刻,有1kw的客户端并发请求。此时服务器的负担真的很大,因此引入了很多技术,其中一个很有效的手段就是:IO多路复用!(一种节流的方式,在同样的请求下,消耗的硬件更少了,本质上就是减少线程的数量)。

解决高并发,其实就是两步走:1、开源:引入更多的硬件资源。2、节流:提高单位硬件资源能够处理的请求数,同样的请求数,消耗的硬件资源更少。

4、String request = sc.next();
此处使用 next() 读取数据,一直读到空白符算结束。那什么是空白符?包括但不限于:换行符(\n:让光标另起一行)、回车符(\r:让光标回到行首(不会另起一行))、空格键、制表符、换页符、垂直制表符…

5、PrintWriter

在这里插入图片描述
访问IO比访问内存的开销大,因此进行IO的次数越多,程序的速度越慢。因此通常会使用一块内存作为缓冲区,写数据的时候,先写到缓冲区里,缓冲区里攒一波数据,统一进行IO。而 PrintWriter 内置缓冲区。printWriter.flush() 是进行手动刷新,就是确保缓冲区里的数据真的通过网卡发出去了,而不是残留在内存缓冲区里,缓冲区内置了一定的刷新策略,例如缓冲区满了,就会触发刷新,例如程序退出,也会出发刷新。

6、
在这里插入图片描述
流对象中持有的资源,有两个部分:1、内存(对象销毁,内存就会被回收)。2、文件描述符。

当 while 循环一圈,内存自然就会被销毁。 在我们服务器端的代码,Scanner 和 PrintWriter 没有持有文件描述符,他们持有的是 inputStream、outputStream 的引用,当 inputStream、outputStream 被销毁之后,Scanner 和 PrintWriter 也都被销毁了;而 inputStream、outputStream 是被 Socket 对象持有的,因此当 Socket 对象被关闭之后,inputStream、outputStream 也就随之被销毁了。

1.3、长/短连接

TCP程序时,涉及到两种写法:1、短连接:一个连接中只传输一次请求和响应。2、长连接:一个连接中可以传输多次请求、连接。

二、应用层协议、传输层协议详解

2.1、应用层(后端开发必知必会)

2.1.1、自定义应用层协议

应用层这一层,有很多现成的协议,也有很多时候,需要我们程序员自己去自定义应用层协议。自定义应用层协议,也是一件很简单的事情。

举个例子:此处有一个需求场景:一个外卖软件,需要在用户打开此软件时,给用户显示用户住址附近的商家列表,列表中有很多项,每一项都包含了一些信息:譬如:商家名称、商家图片、商家店铺好评率,商家与用户的距离、商家评分…(其实外卖软件和服务器之间的沟通,有很多种方式,展示商家列表,只是其中之一)

客户端(用户…):需要给服务器发起一个请求,服务器收到请求之后,就给客户端返回一个响应。[!]那么这个请求里应该包含什么信息呢??该请求应该按照什么格式组织呢??同样的,这个响应应该包含什么信息??应该按照什么格式解析??

此时程序就应该做出如下设计:
1、明确当前程序的请求和响应中都包含哪些信息??(一般在实际开发工作中,请求和响应中都包含哪些信息是根据需求文档里标的来写的)
2、明确具体的请求和响应的格式。[所谓的“明确格式”就是看你按照啥样的方式构造出一个字符串,后续这个字符串就可以作为 tcp/udp的payload进行传输]

明确具体的请求和响应的格式:
示例1:假设此处的请求包含的信息:用户身份、用户当前位置;响应包含的信息:商家名称、商家图片、商家好评率、商家距离用户的位置、商家评分…
请求:1234,80 100\n
响应:蓝胖子肉蟹煲,1.jpg,98%,1km,4.9\n 美蛙鱼头,2.jpg,95%,2km,4.2\n \n
示例1 的响应使用\n来分割每条商家信息。

示例2:
请求:1234;80,100.
响应:蓝胖子肉蟹煲;1.jpg;1km;98%;4.7!美蛙鱼头;2.jpg;2km;95%;4.2!.
示例2 的响应使用!来分割每条商家信息。
其实我们可以看到示例2的商家列表的信息顺序跟示例1并不一样,这是因为这些都是可以自定义的,不需要一样。

示例3:
在这里插入图片描述
从上述几种示例可知,请求和响应的数据组织格式非常灵活,程序员想怎么组织就怎么自定义,当然了,自定义的时候必须要能够保证客户端和服务器这边使用的是相同规则即可。因为在实际开发中,客户端和服务器,往往是由不同的人员负责,因此开发之前,双方就必须共同约定好请求和响应的数据组织格式。

虽然说程序员可以自定义应用层协议,但是为了避免出现过于天马行空的设计,此时行业标准就规定了一些“通用的协议格式”,程序员开发时参考这些格式,就可以在自定义应用层协议时更加严谨、正确。

2.1.2、通用的协议格式

2.1.2.1、XML

xml:是以成对的标签来表示键值对的信息,标签支持嵌套,就可以构成一些更复杂的树形结构数据。
以上面的外卖软件例子为例,使用xml格式来表示 请求:

<request>
   <useId>1234</useId>
   <position> 80 100</position>
</request>

响应:

<response>
   <shops>
      <shop>
        <name>蓝胖子肉蟹煲</name>
        <image>1.jpg</image>
        <distance>1km</distance>
        <rate>98%</rate>
        <star>4.7</star>
      </shop>
    
      <shop>
        <name>美蛙鱼头</name>
        <image>2.jpg</image>
        <distance>2km</distance>
        <rate>95%</rate>
        <star>4.2</star>
      </shop>
   </shops>
</response>

上面的 xml 格式表示的是 键值对 结构。key:userId,value:1234。其实对象本质上也是键值对,属性的名字就是 键,属性的值就是 值。

xml 优缺点:
优点:非常清晰的将结构化数据表示出来了。
缺点:表示数据需要引入大量的标签,看起来繁琐,同时也会占用不少的网络带宽。

其实我们有没有觉得 xml 的编写形式和 html 有些类似,html是编写网页的语言,也是以标签的形式出现。但是 xml 里的标签是程序员自定义的,html 里的标签是有自己的一套使用标准的。(可以把 html 视为是 xml 的特化版本)

2.1.2.2、json

json,当前最主流的一种网络传输数据的格式,本质上也是键值对,但json看起来,比 xml格式 简单便捷、干净很多;json对于换行并不敏感,如果这些内容全都放在一行,也是完全合法的。

一般网络传输时,会对json进行压缩(即去掉不必要的换行和空格),同时把所有数据都放到一行去,要传输的数据其整体占用的带宽就降低了。但可能这样的压缩会影响可读性,不过可以使用一些现成的 json 格式化工具恢复json原有的格式。

在json中,使用 { } 表示键值对,使用 [ ] 表示数组,数组里的每个元素,可以是数字、字符串、字母、或者是其他的 { } 、[ ]…

json格式的请求:
{
userId:1234,
position:“100 80”
}

响应:
{
{
name:“蓝胖子肉蟹煲”
image:“1.jpg”,
distance:“1km”,
rate:98%,
star:4.7
}

{
name:“鱼头”
image:“2.jpg”,
distance:“2km”,
rate:95%,
star:4.2
}
}

json优点:相比于 xml ,表示的数据简洁很多。

2.1.2.3、protobuffer

protobuffer是谷歌提出的一套二进制数据序列化方式,使用二进制的方式,约定几个字节,表示哪个属性。

优点:可以最大程度上节省空间,节省带宽,最大化效率。即不必传输 key,可以根据位置和长度,区分每个属性。
缺点:是二进制数据,无法直接肉眼直接观察,不方便调试。

这类格式很有可能会在工作中用到,尤其是在一些规模复杂的后端服务器。

Java标准库提供好了上述3种序列化方式(数据组织格式),而其他的第3方库,提供的方式更加丰富,后续再介绍。

2.2、传输层

传输层最常见的协议是 UDP、TCP,学习一个协议,不仅要掌握协议的特性,还需要理解协议报文格式

2.2.1、UDP

在这里插入图片描述
我们都知道 UDP 载荷部分里是应用层数据报,那么UDP报头里都有啥,都是啥信息??[重点理解]
在这里插入图片描述
从上图知:一个 UDP报头 含有4部分:1、源端口号。2、目的端口号。3、UDP报文长度。4、校验和。这4个部分都是2个字节的长度,那2个字节,表示的数据范围有多大(这可是最基本的知识点,必须牢记):
(1)、1字节:
有符号:-128 ~ +127
无符号:0~255
(2)、2字节:
有符号:-32768 ~ +32767
无符号:0~65535
(3)、4字节:
有符号:-21亿 ~ +21亿
无符号:0~42亿9千万

在程序中,程序员设定某个这些基本单位时,一定一定要小心,不然程序极易出现错误:

例子1:假如一家游戏公司,使用单位为2字节的某个字段实现游戏的某个功能,我们知道2字节可以表示的数据范围为:0~65535,那么用户在玩游戏时,疯狂玩,此时其收获的成绩峰值就极速上升,上升至了6w,用户还不满足,希望自己的战绩能更好,再继续疯狂玩,但却突然发现,自己的战绩却从6w跌至0。这是不应该的,表示此时程序出现了bug。其实原因就是因为使用了2字节的字段作为表示用户战绩情况,2字节的数据表示范围:0 ~ 65535,当达到最大值之后,数值就无法再继续增大了,会从0重新开始。因此,程序中使用某个字段表示某个功能时,其字段的选择应该要慎重、要考虑其缺陷性。

例子2:假如我们在工作中,被安排了一个任务:记录这一天,公司的搜索浏览器一共有多少请求?假设公司搜索浏览器每天的请求量在10亿量级,此时记录请求的变量,是使用 int 还是 long 类型??

注意:10亿量级,是只有10亿吗??量级此单位,其实是2倍,10亿量级,其实是21亿多。那么此时,变量使用int就不合适了,因为int能够表示的数据范围是 0~65535,变量可以使用long类型,long类型的数据表示范围为 0 ~ 42亿9千万,此时该数据范围完全可以表示 21亿 。

报文长度:
UDP报文长度2个字节,通过换算单位,可得到64kB,因此一个 UDP数据报其最大长度就是64KB(2个字节 = 216,210 = 1KB, 1KB*2^8 = 64KB),那如果说,当前程序使用UDP协议通信,程序想发送的数据超过了64KB,此时怎么使用UDP数据报来携带已超过协议最大长度的数据进行网络传输?1、可以把数据拆分成多组,通过几个UDP数据报进行传输;2、使用 TCP 代替 UDP ,因为 TCP 没有长度限制。不管用啥办法,反正UDP就是不能超过它的最大长度。因为当时行业标准设定UDP的最大长度就是64KB,我们只能遵守这个规则。

源端口、目的端口:
UDP端口号长度2个字节:可以看到 UDP报头 包含 源端口和目的端口,因为端口号使用2字节表示,因此端口号的数据表示范围为0~65535,但对于 1 ~ 1024 的端口号范围,这个范围的端口号已经被一些知名的程序的服务器占用,因此我们写的服务器,很少会用1 ~ 1024 范围的端口号来表示了,一般都是使用 1024之后的端口号表示,不过 1024 之后的端口号也有一些已经被知名程序的服务器占用了,如 3306 已经被 MySQL 程序占用了。

校验和:
其实在网络传输中,受到外界的干扰,传输的数据很容易出错,因为数据传送过程中,本质上是 光信号/电信号/电磁波,这些形式很容易受到磁场、高能粒子射线的干扰。此时就会导致本来你要传输的数据发生比特翻转,如 0 ——> 1、1 ——> 0…此时接收方接收到的数据就是错的。尤其是UDP的长度是64KB,遇上大过64KB的数据就需要进行拆分,将数据分成多组UDP数据发送,此时拆分的数据虽然说是传输过去了,但是对于接收方来说,还需要将数据拼接起来,此时怎么拼接?拼接过程发生了差错怎么办??怎么校验差错??那么,此时协议就通过 校验和 来对网络传输过来的数据进行校验,查看当前数据是否出错。实际的校验和,是会根据数据内容来生成,因此当数据出错,校验和就能感知到数据出错。校验和使用的是CRC校验算法(循环冗余校验和):即把UDP数据报中的每个字节都依次进行累加,把累加结果保存到2个字节的变量中,加着加着,可能就溢出了,但溢出也无所谓,所有字节都加了一遍,最终就得到了校验和。其实在传输数据时,就会把原始数据和校验和一起传递过去,接收方收到数据,同时也收到了发送端传送过来的校验和(旧的校验和),接收方按照同样的方式再算一遍,得到新的校验和。如果新的校验和 与 旧的校验和 相同,则可以视为数据传输过程中,数据是正确的,未发生差错;否则则反之。但是需要注意:数据相同,可推出校验和相同;校验和相同,无法推出数据相同!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1818513.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

kotlin类型检测与类型转换

一、is与!is操作符 1、使用 is 操作符或其否定形式 !is 在运行时检测对象是否符合给定类型。 fun main() {var a "1"if(a is String) {println("a是字符串类型:${a.length}")}// 或val b a is Stringprintln(b) } 二、"不安全的"转换操作符…

ARM32开发--IIC原理

知不足而奋进 望远山而前行 目录 文章目录 前言 目标 内容 I2C通讯规则 I2C写操作 I2C读流程 通讯信号 开始 结束 发送数据 bit发送 Byte发送 等待响应 接收数据 bit接收 Byte接收 发送响应 总结 前言 在现代消费电子和工业电子领域&#xff0c;各种类型的…

如何察觉自己或者家人是否出现了听力问题?

如何察觉自己或者家人是否出现了听力问题呢&#xff1f;可以从以下两个方面观察&#xff1a; 一&#xff0e;社交方面 • 是不是经常需要别人重复刚说的话才能理解&#xff1f; • 多人对话中是否感到吃力&#xff1f; • 觉得别人讲话含糊不清&#xff1f; • 在人多嘈杂…

YASKAWA机器人HW1171921-B电缆维修

安川机器人作为现代工业自动化的重要设备&#xff0c;其稳定运行对于生产线的连续性和效率至关重要。然而&#xff0c;随着使用时间的增长&#xff0c;可能会出现各种YASKAWA机器人本体线缆故障&#xff0c;如断线、短路、接触不良等。 一、安川工业机器人电缆维修前的准备 在进…

【Python】已解决报错 TypeError: Missing 1 Required Positional Argument

本文摘要&#xff1a;【Python】使用 Python 中将字符串转换为数组&#xff0c;并总结提出了几种可用方案。 &#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博…

谁才是产品界的真正王者?AI产品经理对决普通产品经理!

不同类型的产品经理可能有着不同的工作内容&#xff0c;那么&#xff0c;AI产品经理和普通产品经理之间的工作内容、工作职责、技能要求等方面&#xff0c;存在着哪些具体差异&#xff1f;这篇文章里&#xff0c;作者就进行了总结和梳理&#xff0c;一起来看看吧。 一、工作内容…

R语言绘制三变量分区地图

参考资料&#xff1a; https://mp.weixin.qq.com/s/5c7gpO2mJ2BqJevePJz3CQ tricolore包教程&#xff1a;https://github.com/jschoeley/tricolore 学习笔记&#xff1a;Ternary choropleth maps 1、测试实例 代码&#xff1a; library(ggplot2) library(rnaturalearthdata) …

「漏洞复现」I Doc View 在线文档预览 qJvqhFt.json 任意文件读取漏洞(XVE-2024-2115)

0x01 免责声明 请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;作者不为此承担任何责任。工具来自网络&#xff0c;安全性自测&#xff0c;如有侵权请联系删…

手机如何找回我的相册?来看这篇文章,2个方法即刻获取

手机相册已经成为我们存储和分享生活瞬间的重要工具&#xff0c;每当我们在旅行、聚会或其他重要时刻拍摄下一张张珍贵的照片时&#xff0c;相册就成为了我们回味这些瞬间的宝贵载体。然而&#xff0c;当我们不小心删除了相册时&#xff0c;那些曾经美好的回忆似乎也随之消失了…

沸点 | LDBC与SIGMOD联合研讨,推动图数据库创新与标准化

当地时间6月9日&#xff0c;国际基准官方平台关联数据基准委员会&#xff08;LDBC&#xff0c;Linked Data Benchmark Council&#xff09;与SIGMOD 2024&#xff08;是全球最具国际影响力的数据管理、数据处理和数据存储领域的学术顶会之一&#xff0c;ACM SIGMOD/Big Data in…

win11联想版,如何下载Visual Basic 6.0精简版

一、背景 Visual Basic 6.0精简版、Visual Basic Mini&#xff0c;等 Win11系统&#xff0c;网上找压缩包下载&#xff0c;无法成功。 二、解决 通过下载联想应用商店&#xff0c;在应用商店中下载 步骤一 hi&#xff0c;推荐你使用联想应用商店&#xff0c;商店提供上万款…

【大分享03】浙江某区县“个人全生命周期档案”综合智治应用实践

关注我们 - 数字罗塞塔计划 - 本篇是参加由电子文件管理推进联盟联合数字罗塞塔计划发起的“大分享”活动投稿文章&#xff0c;来自杭州安铂数据科技有限公司&#xff0c;作者&#xff1a;智治项目组。 一. 项目概述 根据《政务服务电子文件归档和电子档案管理办法》&#xf…

上午接到被裁员的通知,下午就收到涨薪30%的offer,我生怕公司反悔,当天就找HR签了离职协议,拿到了N+1赔偿!

大家好&#xff0c;我是瑶琴呀。 昨天看到一位网友分享自己被裁的经历&#xff1a;最近这段时间在面试&#xff0c;没成想上午刚被 HR 约谈裁员的事情&#xff0c;下午就收到下家公司涨薪 30% 的offer&#xff0c;这可真是天时人和&#xff0c;当天下午就找 HR 签了离职协议&a…

计算机网络知识点(三)

目录 一、简述TCP连接和关闭的状态转移 二、简述TCP慢启动 三、简述TCP如何保证有序 四、简述TCP常见的拥塞控制算法 五、简述TCP超时重传 一、简述TCP连接和关闭的状态转移 状态转移图 图中上半部分是TCP的三次握手过程的状态变迁&#xff0c;下半部分是TCP四次挥手过程的…

ASCII码表介绍

一、ASCII码是什么 ASCII&#xff08;American Standard Code for Information Interchange&#xff0c;美国信息交换标准代码&#xff09;是基于拉丁字母的一套电脑编码系统。它可分为基于7位二进制数的标准版本和基于8位二进制数的扩展版本&#xff0c;标准版本主要用于显示现…

响应式企业网站建站系统源码 模版丰富+一站式建站 全开源可二次开发 带源码包+搭建部署教程

系统概述 在数字化转型的浪潮中&#xff0c;企业官网作为品牌展示、产品推广及客户服务的重要窗口&#xff0c;其建设质量直接影响着企业的线上形象与市场竞争力。响应式企业网站建站系统源码的出现&#xff0c;为企业提供了一种高效、灵活且成本可控的建站解决方案。 代码示…

如何解除内存卡的写保护并格式化为exFAT文件系统

最近有客户提问内存卡提示写保护&#xff0c;且无法格式化为exFAT格式的问题&#xff0c;可能是由于多种原因引起的。以下是一些可能的解决方法&#xff1a; 1. 检查物理写保护开关 一些SD卡和MicroSD卡适配器上有一个小的物理开关&#xff0c;可以启用或禁用写保护。确保这个…

在线的、完全免费的、提供回放的技术传播方面的大会:Adobe DITA World 2024

▲ 搜索“大龙谈智能内容”关注公众号▲ 最近美国苹果公司召开了WWDC24&#xff0c;国内不少人熬夜观看。 对于我来说&#xff0c;我更关注在美国召开的另外一个会&#xff0c;它就是Adobe DITA world。 一年一度的Adobe DITA world号称是全球最大的DITA营销和技术传播专业人…

云消息队列 ApsaraMQ 成本治理实践(文末附好礼)

作者&#xff1a;家泽、稚柳 前言&#xff1a; 在 AI 原生应用架构浪潮中&#xff0c;消息队列需支持大规模数据和复杂 AI 模型训练与推理场景下的高效异步通信&#xff0c;其成本效益优化也日益受到重视。面对大模型或大数据量&#xff0c;消息量显著增加&#xff0c;云消息…

爱要常觉亏欠,客要一味款待?

一连病了多日&#xff0c;多数时间躺床上静养。今晨上网浏览&#xff0c;见到罗翔先生在其《圆圈正义》一文中&#xff0c;写有以下这样一句话&#xff0c;读后深受启迪&#xff0c;也让笔者更加懂得应当怎样去处理家庭和社会的人际关际。特实录如下&#xff0c;与网友分享。 网…