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

socket编程基础

上一篇 --- 网络基础概念(下)https://blog.csdn.net/Small_entreprene/article/details/147320155?fromshare=blogdetail&sharetype=blogdetail&sharerId=147320155&sharerefer=PC&sharesource=Small_entreprene&sharefrom=from_link

理解源IP地址和目的IP地址

在我们当前的认识当中,IP地址是用来标识主机的唯一性的,后面我们会详细的对IP进行分类。

数据传输到主机并不是最终目的,因为数据是给人使用的。例如,聊天是人在聊天,下载是人在下载,浏览网页是人在浏览。那么,人是如何看到聊天信息、执行下载任务以及浏览网页信息的呢?答案是通过启动的 QQ、迅雷、浏览器等软件。而这些启动的 QQ、迅雷、浏览器等都是进程。换句话说,进程是人在系统中的代表,只要把数据交给进程,人就相当于拿到了数据。

因此,数据传输到主机只是手段,而不是目的。真正的目的是将数据传输到主机内部,并交给主机内的目标进程。

我们上网,其实可以概括成两种行为:

  1. 从远端服务器,获取数据(刷抖音,其实就是将抖音推送到手机端)
  2. 本地数据,上传到远端服务器 (登入,将账号密码推送到远端;上传文件到百度网盘)

不管我们的上网行为有多么丰富多样,在技术角度也就只有两种情况,一种上传,一种下载!因为我们的数据是通过进程来做的,进程又是在内存当中的,上网的时候,所有的数据都是要经过网卡的,而网卡需要将数据给网络。(是进程和网卡之间的关系,网络和网卡的关系)

我们将上面两者两者之间的关系叫做IO!!! 说白了:冯诺依曼体系结构规定,网卡只能进行IO操作,就决定了我们的应用层软件上,只能做获取信息和发送信息的行为。

说明了网络通信的本质就是两个不同主机的进程在进行数据交互,更本质就是进程间通信!

进程间通信的本质就是要看到同一份资源,那么两个不同主机的进程要看到的同一份资源又是谁呢?就是网络!!! (今天只是从在同一台主机内进行进程间通信换成了在不同的两台主机间进行进程间通信而已)

我们现在知道,数据传输到主机只是手段,而不是目的。真正的目的是将数据传输到主机内部,并交给主机内的目标进程。然而,在系统中,同时会存在非常多的进程。因为收到的数据是要分配给一个或多个进程的,哪些数据对应哪一个进程,那么当数据到达目标主机之后,如何将数据转发给目标进程呢?这需要在网络的背景下,通过某种方式在系统中标识主机的唯一性,从而确保数据能够准确地被转发到目标进程。

 我们主机会收到来自远端主机发送来的各种数据,这些数据需要按照对应不同的数据分发到对应的进程当中,所以我们就必须要在系统层面上有一种办法来标识主机的唯一性,为了能够实现主机唯一性的标识,我们在网络的范畴当中,我们就引入了新的概念:端口号!

认识端口号

端口号(Port)是传输层协议的内容。

  • 端口号是一个2字节16位的整数。

  • 端口号用来标识一个进程,告诉操作系统,当前的这个数据要交给哪一个进程来处理。(也就是说,未来写的网络服务,比如说QQ,这个网络服务要进行启动的时候,需要通过操作系统提供的一些系统调用来让这个进行和对应的端口号(在传输层提取报文中的目的端口号)产生对应的关联)

  • IP地址 + 端口号能够标识网络上的某一台主机的某一个进程。

  • 一个端口号只能被一个进程占用。(就是端口号可以用来标识系统中唯一的一个网络进程!!!)(其实反过来,一个进程是可以和多个端口号进行绑定的,因为我们要的是从端口号查进程的方向是唯一的)

网络通信的本质是全网范围内唯二的两个进程在进行进程间通信!!!我们用对方的IP和Port标识对方的唯一性。我们将IP+Port称为Socket(套接字)

不过,端口号端口号可以用来标识系统中唯一的一个网络进程,但是我们学习过,pid也是进程的唯一标识,那为什么不直接用进程pid呢?

不是所有的进程都需要进行网络通信,不过我们从技术角度上来说,使用pid不使用端口号,这是可行的,但是pid是一个系统的概念,如果未来pid这个概念变化了,伴随着网络就需要变,这就是耦合性差,使用端口号就可以进行解耦!!!


端口号的范围划分是【0,65535】,因为是一个两字节(16比特位)的整数

  • 0 - 1023:知名端口号,HTTP、FTP、SSH 等这些广为使用的应用层协议,它们的端口号都是固定的。
  • 1024 - 65535:操作系统动态分配的端口号。客户端程序的端口号,就是由操作系统从这个范围分配的。

传输层协议(TCP 和 UDP)的数据段中有两个端口号,分别叫做源端口号和目的端口号,就是在描述“数据是哪台主机的哪一个进程发的,要发给哪台主机上的哪一个进程”。


理解socket

综上,IP 地址用来标识互联网中唯一的一台主机,port 用来标识该主机上唯一的一个网络进程。

  • IP + Port 就能表示互联网中唯一的一个进程。

  • 所以,通信的时候,本质是两个互联网进程代表人来进行通信,{srcIp,srcPort,dstIp,dstPort}这样的 4 元组就能标识互联网中唯二的两个进程。

  • 所以,网络通信的本质,也是进程间通信。

  • 我们把 ip + port 叫做套接字 socket。


传输层的典型代表

如果我们了解了系统,也了解了网络协议栈,我们就会清楚,传输层是属于内核的。那么我们要通过网络协议栈进行通信,必定调用的是传输层提供的系统调用,来进行网络通信。

传输层有两个重要协议:TCB和UDP。 

认识 TCP 协议

此处我们先对 TCP(Transmission Control Protocol 传输控制协议)有一个直观的认识;后面我们再详细讨论 TCP 的一些细节问题。

  • 传输层协议

  • 有连接:在数据传输之前,需要先建立连接。(打电话,你喂我喂的过程就是建立连接的过程)

  • 可靠传输:保证数据的完整性和顺序性,通过确认和重传机制确保数据可靠传输。

  • 面向字节流:数据以字节流的形式传输,不保留消息边界。(自来水,怎么接,接多少,都是自己自主决定的;文件打开也叫文件流,字节流和文件流没有区别,都是流式的;学习完自定义协议后我们就能理解了)

认识 UDP 协议

此处我们也是对 UDP(User Datagram Protocol 用户数据报协议)有一个直观的认识;后面再详细讨论。

  • 传输层协议

  • 无连接:不需要建立连接,直接发送数据。(对讲机)

  • 不可靠传输:不保证数据的完整性和顺序性,数据可能丢失或乱序到达。

  • 面向数据报:数据以数据报的形式传输,保留消息边界。(发快递,发几个就只能几个)

TCP是可靠的,丢包了可以再发,但是UDP不可靠,那为什么还要保留UDP呢?(属于同层协议,但是还保留一个不可靠的???)

我们要注意,这里的可靠和不可靠不可以将其视为贬义词,而是一种中性词,是一种特点。TCP保证可靠性,意味着他一定要做更多的工作,也就是意味着TCP协议会更加复杂一些,复杂带来的就是占有资源会比较多。UDP协议就会很简单,简单的话就是代表开发周期短,可维护性好。

因为我们暂时还没有深入了解 TCP 和 UDP 协议,此处只做了解即可。


网络字节序

我们以前学过,计算机在存储数据的时候,是有大端和小端的,大小端是按照字节为单位的。

大端(Big-Endian)

定义:大端字节序是指高位字节存放在内存的低地址端,低位字节存放在内存的高地址端。

 假设有一个32位的整数 0x12345678,在大端字节序下,它在内存中的存储顺序如下:

内存地址: 0x00  0x01  0x02  0x03
存储内容: 12    34    56    78
  • 0x12 存储在最低地址 0x00

  • 0x78 存储在最高地址 0x03

小端(Little-Endian)(小-小-小)

定义:小端字节序是指低位字节存放在内存的低地址端,高位字节存放在内存的高地址端。

假设有一个32位的整数 0x12345678,在小端字节序下,它在内存中的存储顺序如下:

内存地址: 0x00  0x01  0x02  0x03
存储内容: 78    56    34    12
  • 0x78 (低权值位:就是16的几次方)存储在最低地址 0x00

  • 0x12 存储在最高地址 0x03

#include <stdio.h>// 函数:将整数从当前字节序转换为网络字节序(大端)
unsigned int htonl(unsigned int hostlong) {unsigned char *bytes = (unsigned char*)&hostlong;return ((unsigned int)(bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]);
}int main() {unsigned int x = 1;if (*((char *)&x) == 0) {printf("大端(Big-Endian)\n");} else {printf("小端(Little-Endian)\n");printf("转换前的值:%u\n", x);// 调用 htonl 函数将整数转换为大端字节序x = htonl(x);printf("转换后(大端)的值:%u\n", x);}return 0;
}

如果今天主机A是小端存储,主机B是大端存储,两台主机间要进行网络通信,A将数据发送给B的话,主机B就解释反了。所以在网络当中,两台主机,如果主机间的存储序列不同的话,经过网络通信,会导致对方将接收到的数据解释错了!

所以在网络中就有规定:凡是将数据发送到网络当中的话,一定是要按照大端的形式发送!

发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出。接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存。因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址。TCP/IP 协议规定,网络数据流应采用大端字节序,即低地址高字节。不管这台主机是大端机还是小端机,都会按照这个 TCP/IP 规定的网络字节序来发送/接收数据。如果当前发送主机是小端,就需要先将数据转成大端;否则就忽略,直接发送即可。

为使网络程序具有可移植性,使同样的 C 代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换。

  • 这些函数名很好记,h 表示 host,n 表示 network,l 表示 32 位长整数,s 表示 16 位短整数。

  • 例如,htonl 表示将 32 位的长整数从主机字节序转换为网络字节序,例如将 IP 地址转换后准备发送。

  • 如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回。

  • 如果主机是大端字节序,这些函数不做转换,将参数原封不动地返回。

注意:所有发送到网络上的数据,都必须是大端的!

socket编程接口

socket常见API

// 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
int socket(int domain, int type, int protocol);// 绑定端口号 (TCP/UDP, 服务器)
int bind(int socket, const struct sockaddr *address, socklen_t address_len);// 开始监听 socket (TCP, 服务器)
int listen(int socket, int backlog);// 接收请求 (TCP, 服务器)
int accept(int socket, struct sockaddr* address, socklen_t* address_len);// 建立连接 (TCP, 客户端)
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

这些API的详细细节我们会在后续写代码的时候进行说明。

我们发现大部分的接口参数中都有const struct sockaddr*的结构体指针(其他暂时不关心)

下面,我们来聊一聊这个sockaddr这个结构体。

sockaddr结构体

我们现在清楚,网络通信的本质其实是进程间通信,我们之前学习的system V这个标准属于本地之间进行进程间通信,我们后面还会见到的POSIX标准,这个是主要用于网络通信的,网络通信也是进程通信,也能进行本地通信的,也就是为什么我们之前说System V版本的进程间通信被淘汰了,因为POSIX这套标准,我们直接就可以进行了,还顺带了网络通信。

socket套接字会有许多不同的种类来满足各种各样的不同的应用场景--网络socket/本地socket(unix域间通信)/原始socket,原始socket我们不需要考虑,未来我们只需要学懂网络socket,本地socket我们自然而然也就清楚了。也是正因为有不同的场景的socket,我们socket未来的接口,也是会有不同的通信接口规范(网络的一套,本地的一套......)但是socket的设计者并不想这么干,只想要提供一套通信接口!!!(这一套既可以做网络通信,也可以做本地通信)

所以就需要对接口进行设计,为了能够支持设计出来的接口可以进行不同种类的通信,就设计了一个结构体---sockaddr结构体!

  • 通用性struct sockaddr 提供了一个通用的接口,适用于各种网络协议。

  • 专用性struct sockaddr_instruct sockaddr_un 分别针对IPv4网络通信和本地通信进行了优化,提供了必要的信息和灵活性。

在网络编程中,sockaddr 结构体及其相关的结构体如 sockaddr_insockaddr_un 经常需要进行强制类型转换。这是因为 sockaddr 是一个通用的地址结构体,设计用来支持多种不同的网络协议和地址类型。而 sockaddr_insockaddr_un 是针对特定协议(如IPv4、IPv6和UNIX域套接字)的具体实现。

当你需要将 sockaddr_insockaddr_un 结构体传递给需要 sockaddr 类型参数的函数时,通常需要进行强制类型转换。例如,在调用 bind()connect() 函数时,你需要将 sockaddr_in 结构体的地址转换为 sockaddr 类型的指针。

这样做的原因是因为 sockaddr 结构体定义了一个通用的接口,它包含了一个地址族字段(sa_family),用于指示地址的具体类型。sockaddr_insockaddr_un 结构体都以这个地址族字段开始,但它们包含的地址信息不同。通过将它们转换为 sockaddr 类型,你可以确保函数能够正确识别和处理不同类型的地址。

至于为什么不将参数设置为 void*,原因在于 void* 类型虽然可以指向任何类型的数据,但它不提供足够的信息来处理不同协议的地址。使用 sockaddr 类型及其派生的结构体可以提供必要的语义信息,使函数能够根据地址类型字段来正确处理地址数据。此外,原始套接字API是在1983年发布的,早于1989年的ANSI C标准,其前身——K&R C——根本没有 void *,所以您无论如何都必须将其转换为某个东西。

其实本质就是继承和多态:(C语言实现的)



相关文章:

socket编程基础

上一篇 --- 网络基础概念&#xff08;下&#xff09;https://blog.csdn.net/Small_entreprene/article/details/147320155?fromshareblogdetail&sharetypeblogdetail&sharerId147320155&sharereferPC&sharesourceSmall_entreprene&sharefromfrom_link 理…...

根据定义给出json_schema:

根据您提供的智能体定义&#xff0c;以下是符合JSON Schema Draft-07规范的完整架构描述&#xff08;包含中文注释说明&#xff09;&#xff1a; {"$schema": ""title": "智能体架构规范","type": "object","req…...

深入微服务核心:从架构设计到规模化

作者&#xff1a;腾讯云开发者 原文&#xff1a;深入微服务核心&#xff1a;从架构设计到规模化 01 微服务 什么是微服务&#xff1f; 微服务就是一些协同工作的小而自治的服务。我们在一个单体系统中&#xff0c;通常会采用一些抽象层或者模块来保证代码的内聚性&#xff0c…...

linux与c语言基础知识(未全部完成)

文章很多处理论&#xff0c;没办法写出来&#xff0c;&#xff08;linux的一些理论问题&#xff0c;我有时间后&#xff0c;会逐个解决&#xff09; 文章大多数的理论来字这个链接&#xff0c; C语言快速入门-C语言基础知识-CSDN博客 一. linux&#xff08;Ubuntu&#xff09; …...

【专题刷题】滑动窗口(四):

&#x1f4dd;前言说明&#xff1a; 本专栏主要记录本人的基础算法学习以及LeetCode刷题记录&#xff0c;按专题划分每题主要记录&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代码&#xff1b;&#xff08;2&#xff09;优质解法 优质代码&#xff1b;&#xff…...

小白自学python第一天

学习python的第一天 一、常用的值类型&#xff08;先来粗略认识一下~&#xff09; 类型说明数字&#xff08;number&#xff09;包含整型&#xff08;int&#xff09;、浮点型&#xff08;float&#xff09;、复数&#xff08;complex&#xff09;、布尔&#xff08;boolean&…...

Redis 服务自动开启、设置密码和闪退问题

一、Redis 服务自动开启 1、以管理员身份运行命令提示符 右键点击“命令提示符”图标&#xff0c;选择“以管理员身份运行”。 2、注册为 Windows 服务 redis-server --service-install 3、启动服务 redis-server --service-start 4、测试 Redis 连接 redis-cli ping …...

2025年渗透测试面试题总结-拷打题库14(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 2025年渗透测试面试题总结-拷打题库14 1. WAF存在的意义 2. 威胁感知能力衡量指标 3. 感知规则有效性…...

java后端开发day35--集合进阶(四)--双列集合:MapHashMapTreeMap

&#xff08;以下内容全部来自上述课程&#xff09; 1.双列集合 1.1 特点 双列集合一次需要存一对数据&#xff0c;分别为键和值键不能重复&#xff0c;值可以重复键和值是一一对应的&#xff0c;每一个键只能找到自己对应的值键值这个整体&#xff0c;我们称之为“键值对”…...

进行网页开发时,怎样把function()中变量值在控制台输出,查看?

在网页开发过程中&#xff0c;为了及时了解JavaScript中的function函数中的变量值&#xff0c;可以用控制台命令console.log()把变量的值在控制台输出&#xff0c;方便调试时对函数变量值进行了解。 看下面的一段示例&#xff1a; <!DOCTYPE html> <html> &l…...

【计算机网络】现代网络技术核心架构与实战解析

目录 前言技术背景与价值当前技术痛点解决方案概述目标读者说明 一、技术原理剖析核心概念图解核心作用讲解关键技术模块说明技术选型对比 二、实战演示环境配置要求核心代码实现案例1&#xff1a;TCP服务端/客户端通信案例2&#xff1a;Wireshark抓包分析 三、性能对比测试方法…...

Python内置函数---bool()

用于将任意对象转换为布尔值&#xff08;True或False&#xff09; 1. 基本语法与参数 bool(x) - 参数&#xff1a;x为可选参数&#xff0c;可以是任意Python对象&#xff08;如数值、字符串、列表、自定义对象等&#xff09;。 - 返回值&#xff1a;根据x的真值性返回True或Fa…...

Vue 3中如何封装API请求:提升开发效率的最佳实践

在现代前端开发中&#xff0c;API请求是不可避免的一部分&#xff0c;尤其是与后端交互时。随着Vue 3的广泛应用&#xff0c;如何高效地封装API请求&#xff0c;既能提升代码的可维护性&#xff0c;又能确保代码的高复用性&#xff0c;成为了很多开发者关注的话题。 在本文中&…...

【Redis】redis主从哨兵

Redis 主从复制 在访问量极高的场景下&#xff0c;单台 Redis 已难以承载所有请求&#xff0c;且单点故障风险高。通过主从复制&#xff0c;可以实现读写分离、数据备份与高可用。 概念 主节点&#xff08;Master&#xff09;&#xff1a;负责写操作&#xff0c;将数据变更同…...

16.第二阶段x64游戏实战-分析二叉树结构

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 上一个内容&#xff1a;15.第二阶段x64游戏实战-分析怪物血量&#xff08;遍历周围&#xff09; 首先通…...

vue | 不同 vue 版本对复杂泛型的支持情况 · vue3.2 VS vue3.5

省流总结&#xff1a;defineProps 的泛型能力&#xff0c;来直接推导第三方组件的 props 类型 引入第三方库的类型&#xff0c;并直接在 <script setup> 中作为 props 使用。这种类型一般是复杂泛型&#xff08;包含联合类型、可选属性、交叉类型、条件类型等&#xff0…...

OpenGL学习笔记(Blinn-Phong、伽马矫正、阴影)

目录 Blinn-PhongGamma矫正GammaGamma矫正实现方法sRGB纹理衰减 阴影shadow mapping渲染阴影改进阴影贴图PCF GitHub主页&#xff1a;https://github.com/sdpyy1 OpenGL学习仓库:https://github.com/sdpyy1/CppLearn/tree/main/OpenGLtree/main/OpenGL):https://github.com/sdp…...

GPLT-2025年第十届团体程序设计天梯赛总决赛题解(2025天梯赛题解,266分)

今天偶然发现天梯赛的代码还保存着&#xff0c;于是决定写下这篇题解&#xff0c;也算是复盘一下了 L1本来是打算写的稳妥点&#xff0c;最后在L1-6又想省时间&#xff0c;又忘记了insert&#xff0c;replace这些方法怎么用&#xff0c;也不想花时间写一个文件测试&#xff0c…...

day4 pandas学习

%pip install openxyxl 找一个自己觉得有意思的文件。我找的是成绩单来玩。 这节学的比较耗时了&#xff0c;大概用了60分钟。 import pandas as pd data2 pd.read_csv(rD:\python代码区\代码随想录挑战-调试区\python训练营\1_计算类专业分流学生成绩排名.csv) #print(data)…...

【Java学习笔记】循环结构

循环结构 一、for循环 for循环结构 for(循环变量初始化;循环条件;循环变量迭代){循环操作&#xff08;可以多条语句&#xff09; }for循环写死循环 for(;;){语句 }注意点&#xff1a;循环变量的初始化在for语句内&#xff0c;属于是局部变量&#xff0c;在全局中会出现未定义…...

URP-UGUI交互功能实现

一、非代码层面实现交互&#xff08;SetActive&#xff09; Button &#xff1a;在OnClick&#xff08;&#xff09;中添加SetActive方法&#xff08;但是此时只首次有效&#xff09; Toggle &#xff1a;在OnClick&#xff08;&#xff09;中添加动态的SetActive方法 &#…...

08-IDEA企业开发工具-集成AI插件通义灵码

需要登陆才可使用&#xff01;&#xff01;&#xff01; 1. 安装AI编程插件 找到插件: 在IDEA的设置中&#xff0c;找到插件&#xff08;Plugins&#xff09;部分。安装插件: 搜索“通义灵码”&#xff0c;找到后点击安装&#xff08;Install&#xff09;&#xff0c;接受条款…...

解决报错:this[kHandle] = new _Hash(algorithm, xofLen);

前端项目编译报错&#xff1a; node:internal/crypto/hash:68this[kHandle] new _Hash(algorithm, xofLen);^Error: error:0308010C:digital envelope routines::unsupportedat new Hash (node:internal/crypto/hash:68:19)at Object.createHash (node:crypto:138:10)at modu…...

使用 Streamlit 打造一个简单的照片墙应用

在现代 web 开发中&#xff0c;快速构建交互式应用是一项重要的技能。Streamlit 是一个强大的 Python 库&#xff0c;允许开发者以最小的代码量创建美观且功能丰富的 web 应用。今天&#xff0c;我们将通过分析一段简单的 Streamlit 代码&#xff0c;展示如何构建一个照片墙应用…...

深度学习优化器和调度器的选择和推荐

一、常用优化器对比 1. 随机梯度下降&#xff08;SGD&#xff09; 原理&#xff1a;每次迭代使用小批量数据计算梯度并更新参数。优点&#xff1a;实现简单&#xff0c;适合大规模数据集。缺点&#xff1a;收敛速度慢&#xff0c;容易陷入局部最优或鞍点。适用场景&#xff1…...

“时间”,在数据处理中的真身——弼马温一般『无所不能』(DeepSeek)

电子表格时间处理真理&#xff1a;数值存储最瘦身&#xff0c;真身闯关通四海。 笔记模板由python脚本于2025-04-23 22:25:59创建&#xff0c;本篇笔记适合喜欢在电子表格中探求时间格式的coder翻阅。 【学习的细节是欢悦的历程】 博客的核心价值&#xff1a;在于输出思考与经验…...

为什么Spring中@Bean注解默认创建单例Bean

在Spring框架中&#xff0c;使用Bean注解定义的对象默认确实是单例的&#xff0c;这是由Spring容器的设计哲学和实际需求决定的。下面我从多个角度解释这一设计选择的原因和机制。 1. Spring Bean作用域基础 Spring定义了多种Bean作用域&#xff0c;其中默认是单例(Singleton…...

GPLT-2025年第十届团体程序设计天梯赛总决赛题解(2025天梯赛题解,共计266分)

今天偶然发现天梯赛的代码还保存着&#xff0c;于是决定写下这篇题解&#xff0c;也算是复盘一下了 L1本来是打算写的稳妥点&#xff0c;最后在L1-6又想省时间&#xff0c;又忘记了insert&#xff0c;replace这些方法怎么用&#xff0c;也不想花时间写一个文件测试&#xff0c…...

JDK(Ubuntu 18.04.6 LTS)安装笔记

一、前言 本文与【MySQL 8&#xff08;Ubuntu 18.04.6 LTS&#xff09;安装笔记】同批次&#xff1a;先搭建数据库&#xff0c;再安装JDK&#xff0c;后面肯定就是部署Web应用&#xff1a;典型的单机部署。“麻雀虽小五脏俱全”&#xff0c;善始善终&#xff0c;还是记下来吧。…...

Java 拦截器完全指南:原理、实战与最佳实践

一、引言 拦截器的基本概念 在现代 Java Web 开发中&#xff0c;拦截器&#xff08;Interceptor&#xff09;是一种用于在请求处理前后插入自定义逻辑的机制。简单来说&#xff0c;它是一种“横切逻辑处理器”&#xff0c;可以用来对请求进行预处理、后处理&#xff0c;甚至终…...

2025.04.23华为机考第二题-200分

📌 点击直达笔试专栏 👉《大厂笔试突围》 💻 春秋招笔试突围在线OJ 👉 笔试突围OJ 02. 魔法彩灯森林 问题描述 在卢小姐的魔法花园中,有一棵神奇的彩灯树。这棵树的每个节点都装有一盏魔法灯,灯有三种颜色状态:红色(用数字1表示)、绿色(用数字2表示)和蓝色(…...

【Leetcode 每日一题】1399. 统计最大组的数目

问题背景 给你一个整数 n n n。请你先求出从 1 1 1 到 n n n 的每个整数 10 10 10 进制表示下的数位和&#xff08;每一位上的数字相加&#xff09;&#xff0c;然后把数位和相等的数字放到同一个组中。 请你统计每个组中的数字数目&#xff0c;并返回数字数目并列最多的组…...

系统重装——联想sharkbay主板电脑

上周给一台老电脑重装系统系统&#xff0c;型号是lenovo sharkbay主板的电脑&#xff0c;趁着最近固态便宜&#xff0c;入手了两块长城的固态&#xff0c;装上以后插上启动U盘&#xff0c;死活进不去boot系统。提示 bootmgr 缺失&#xff0c;上网查了许久&#xff0c;终于解决了…...

Python数据清洗笔记(上)

一、数据清洗概述 数据清洗是数据分析过程中至关重要的一步&#xff0c;约占整个数据分析过程的60%-80%的时间。主要包括处理缺失值、异常值、重复值、格式不一致等问题。 二、常用工具 主要使用Python的Pandas库进行数据清洗&#xff1a; import pandas as pd import nump…...

三、Python编程基础03

目录 一、debug 调试的使用1. 打断点2. 右键 Debug 运行代码3. 单步执行代码,查看过程 二、字符串1、定义与下标引用2、切片3、查找4、去除空白字符5、转换大小写与拆分6、其他方法-替换、连接、是否为纯数字7、登录案例优化 三、列表 list1、列表基础操作2、案例&#xff1a; …...

西门子S7-200SMART 控制Profinet闭环步进MD-4250-PN (1)电机及专栏介绍

一、前言 本系列是我继 《西门子S7-1200PLC 控制步进电机 MD-4240-PN》系列专栏后&#xff0c;新开的一篇专栏。 系列的主题围绕 S7-200SMART Profinet闭环步进(MD-4250-PN) 触摸屏的硬件&#xff0c;预计作四篇文章&#xff0c;分别为&#xff1a;专栏介绍、硬件介绍、PLC…...

NoSQL 简单讲解

目录 1. NoSQL 的背景与意义 1.1 数据库的演变 1.2 NoSQL 的兴起 2. NoSQL 数据库的分类 2.1 键值存储&#xff08;Key-Value Stores&#xff09; 2.2 文档数据库&#xff08;Document Stores&#xff09; 2.3 列族存储&#xff08;Column-Family Stores&#xff09; 2.…...

TCP 协议:原理、机制与应用

一、引言 在当今数字化的时代&#xff0c;网络通信无处不在&#xff0c;而 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;作为互联网协议栈中的核心协议之一&#xff0c;扮演着至关重要的角色。无论是浏览网页、发送电子邮件还是进行文件…...

C++23 新特性:令声明顺序决定非静态类数据成员的布局 (P1847R4)

文章目录 引言背景知识非静态类数据成员类的内存布局 P1847R4提案内容示例代码 影响和优势提高代码的可预测性与其他语言和库的交互更加方便简化代码调试和优化 编译器支持情况实际应用场景嵌入式系统开发跨语言编程内存优化 总结 引言 在C的发展历程中&#xff0c;每一个新版…...

Java 环境配置详解(Windows、macOS、Linux)

Java 环境配置是学习和开发 Java 程序的第一步&#xff0c;也是至关重要的一步。一个正确配置的 Java 环境能够保证你的 Java 程序能够顺利编译、运行和调试。本文将详细介绍在 Windows、macOS 和 Linux 三种主流操作系统上配置 Java 环境的步骤&#xff0c;力求详尽、易懂&…...

ChatBEV:一种理解 BEV 地图的可视化语言模型

25年3月来自上海交大、上海AI实验室、同济大学和MAGIC的论文“ChatBEV: A Visual Language Model that Understands BEV Maps”。 交通场景理解对于智能交通系统和自动驾驶至关重要&#xff0c;可确保车辆安全高效地运行。虽然 VLM 的最新进展已显示出整体场景理解的前景&…...

利用Python爬虫实现百度图片搜索的PNG图片下载

在图像识别、训练数据集构建等场景中&#xff0c;我们经常需要从互联网上批量下载图片素材。百度图片是中文搜索中最常用的来源之一。本文将介绍如何使用Python构建一个稳定、可扩展的百度图片爬虫&#xff0c;专门用于下载并保存高清PNG格式图片。 一、项目目标 本项目的目标…...

自主可控鸿道Intewell工业实时操作系统

鸿道Intewell工业实时操作系统是东土科技旗下科东软件自主研发的新一代智能工业操作系统&#xff0c;以下是相关介绍&#xff1a; 系统架构 -Intewell-C全实时构型&#xff1a;设备上只运行自研RTOS的全实时系统&#xff0c;适用于有功能安全认证需求的实时控制场景&#xf…...

【数据结构入门训练DAY-21】信息学奥赛一本通T1334-围圈报数

文章目录 前言一、题目二、解题思路结语 前言 本次训练内容 STL库中队列的使用练习。训练解题思维 一、题目 有&#xff4e;个人依次围成一圈&#xff0c;从第&#xff11;个人开始报数&#xff0c;数到第&#xff4d;个人出列&#xff0c;然后从出列的下一个人开始报数&am…...

【C语言】C语言中的字符函数和字符串函数全解析

前言 在C语言编程中&#xff0c;字符和字符串的处理是必不可少的。C语言标准库提供了丰富的字符和字符串函数&#xff0c;这些函数极大地简化了字符和字符串的操作。本文将详细介绍这些函数的使用方法、模拟实现以及一些实用的代码示例&#xff0c;帮助你更好地理解和掌握它们…...

声纹振动传感器在电力监测领域的应用

声纹振动传感器在电力监测领域有多种应用&#xff0c;主要包括以下几个方面&#xff1a; 变压器监测 故障诊断&#xff1a;变压器在运行过程中会产生特定的声纹和振动信号&#xff0c;当变压器内部出现故障&#xff0c;如绕组短路、铁芯松动、局部放电等&#xff0c;其声纹和振…...

配色之道:解码产品设计中的UI设计配色艺术

在数字化时代&#xff0c;用户界面&#xff08;UI&#xff09;作为产品与用户交互的桥梁&#xff0c;其设计质量直接影响着用户体验与产品成败。而配色&#xff0c;作为UI设计中最为直观且富有表现力的元素之一&#xff0c;不仅是视觉美学的体现&#xff0c;更是情感传递、信息…...

python基础语法测试

1. 关于Python语言数值操作符&#xff0c;以下选项中描述错误的是 A x%y表示x与y之商的余数&#xff0c;也称为模运算 B x/y表示x与y之商 C x**y表示x的y次幂&#xff0c;其中&#xff0c;y必须是整数 D x//y表示x与y之整数商&#xff0c;即不大于x与y之商的最大整数2. 下面代码…...

如何安装Visio(win10)

首先下载下面这些文件 HomeStudent2021Retail.img officedeploymenttool_17531-20046.exe office中文语言包.exe 确保这些文件都在一个文件夹内&#xff08;我已经上传这些资源&#xff0c;这些资源都是官网下载的&#xff09; 官网资源下载教程 1.下载Office镜像&#xff0…...

Sql刷题日志(day5)

面试&#xff1a; 1、从数据分析角度&#xff0c;推荐模块怎么用指标衡量&#xff1f; 推荐模块主要目的是将用户进行转化&#xff0c;所以其主指标是推荐的转化率推荐模块的指标一般都通过埋点去收集用户的行为并完成相应的计算而形成相应的指标数据&#xff0c;而这里的驱动…...