Linux之netlink(2)libnl使用介绍(1)

Linux之netlink(2)Libnl3使用介绍(1)

Author:Onceday Date:2025年4月26日

漫漫长路,才刚刚开始…

全系列文章可查看专栏: Linux内核知识_Once-Day的博客-CSDN博客

本文翻译自libnl3官方文档:Netlink Library (libnl)

参考文档:

  • thom311/libnl: Netlink Library Suite
  • libnl - Netlink Protocol Library Suite
  • Routing Family Netlink Library (libnl-route)
  • Netlink Library (libnl)
  • Documentation Overview - libnl Suite

文章目录

      • Linux之netlink(2)Libnl3使用介绍(1)
        • 1. libnl介绍
        • 2. Netlink协议介绍
          • 2.1 Netlink地址
          • 2.2 消息格式
          • 2.3 消息类型
          • 2.4 序列号
        • 3. Netlink套接字
          • 3.1 Socket实例
          • 3.2 序列号
          • 3.3 多播组
          • 3.4 回调函数配置
          • 3.5 套接字属性

1. libnl介绍

libnl3是Linux平台上一个功能丰富的网络编程库。它为用户空间程序提供了一组全面的API,用于与Linux内核的网络组件进行交互。libnl3让开发者能够方便地配置和管理各种网络功能,如链路、接口、路由、地址、邻居、策略路由、流量控制、网络状态监控等。

libnl 套件是一组库的集合,它为基于 Netlink 协议的 Linux 内核接口提供了应用程序编程接口(API)。

Netlink 是一种主要在内核与用户空间进程之间使用的进程间通信(IPC)机制。它被设计成是 ioctl(输入输出控制)更灵活的替代方案,主要用于提供与网络相关的内核配置和监控接口。

在这里插入图片描述

这些接口被划分到几个小型库中,这样就不会强制应用程序链接到一个庞大臃肿的单一库上。

  • libnl,核心库,实现了使用 Netlink 协议所需的基本功能,比如套接字处理、消息构建与解析,以及数据的发送和接收。这个库保持小巧且简约。该套件中的其他库都依赖于这个库。
  • libnl-route,提供了 NETLINK_ROUTE 系列配置接口的 API,这些接口涉及网络接口、路由、地址、邻居节点以及流量控制等方面。
  • libnl-genl,提供了通用 Netlink 协议(Netlink 协议的扩展版本)的 API。
  • libnl-nf,提供了基于 Netlink 的 netfilter(网络过滤器)配置和监控接口(连接跟踪、日志记录、队列)的 API。

主要的头文件是 <netlink/netlink.h>。根据程序所使用的子系统和组件的不同,可能还需要在源文件中包含其他的头文件。

#include <netlink/netlink.h>#include <netlink/cache.h>#include <netlink/route/link.h>

如果该库在编译时启用了调试语句,那么当环境变量 NLDBG 的值设置为大于 0 时,它将会把调试信息打印到标准错误输出(stderr)中。

NLDBG=2 ./myprogram

下面是各个NLDBG值对应的调试级别:

调试级别描述
0调试功能已禁用(默认设置)
1警告、重要事件及通知信息
2或多或少较为重要的调试消息
3会产生大量调试消息的重复性事件相关信息
4甚至更不太重要的消息

查看与其他套接字交换的 Netlink 消息流通常是很有用的。设置环境变量 NLCB=debug 将启用调试消息处理程序,该程序进而会以人类可读的格式将交换的 Netlink 消息打印到标准错误输出(stderr)中。

$ NLCB=debug ./myprogram-- Debug: Sent Message:--------------------------   BEGIN NETLINK MESSAGE ---------------------------[HEADER] 16 octets.nlmsg_len = 20.nlmsg_type = 18 <route/link::get>.nlmsg_flags = 773 <REQUEST,ACK,ROOT,MATCH>.nlmsg_seq = 1301410712.nlmsg_pid = 20014[PAYLOAD] 16 octets
.....
2. Netlink协议介绍
2.1 Netlink地址

Netlink 协议是一种基于套接字的进程间通信(IPC)机制,用于用户空间进程与内核之间,或者用户空间进程彼此之间的通信。Netlink 协议基于 BSD 套接字,并使用 AF_NETLINK 地址族。每一种 Netlink 协议都有其自身的协议编号(例如,NETLINK_ROUTE、NETLINK_NETFILTER 等)。它的编址模式基于一个 32 位的端口号,以前称为进程标识符(PID),这个端口号唯一标识每个通信对等端。

Netlink 地址(端口)由一个 32 位整数组成。端口 0(零)是为内核保留的,它指的是每个 Netlink 协议族在内核端的套接字。其他端口号通常指的是用户空间所拥有的套接字,不过这并非强制规定。

起初,常见的做法是使用进程标识符(PID)作为本地端口号。但随着支持多线程的 Netlink 应用程序以及需要多个套接字的应用程序的出现,这种做法变得不太实用了。因此,libnl 库会基于进程标识符生成唯一的端口号,并为其添加一个偏移量,从而允许使用多个套接字。出于向后兼容的原因,初始套接字的端口号仍然会等于进程标识符。

在这里插入图片描述

上图展示了三个应用程序以及内核端所暴露的两个内核端套接字。它呈现了常见的 Netlink 使用场景:

  • 用户空间到内核。
  • 用户空间到用户空间。
  • 监听内核的多播通知。

(1)用户空间到内核:Netlink 最常见的使用形式是用户空间应用程序向内核发送请求,并处理回复,回复内容要么是错误消息,要么是成功通知。

在这里插入图片描述

(2)用户空间到用户空间:Netlink 也可以用作一种进程间通信机制,以便用户空间应用程序之间直接进行通信。通信并不局限于两个对等端,任意数量的对等端都可以相互通信,并且多播功能允许通过一条消息发送给多个对等端。

为了让各个套接字能够相互可见,必须为相同的 Netlink 协议族创建这两个套接字。

在这里插入图片描述

(3)用户空间监听内核通知:这种形式的 Netlink 通信通常出现在用户空间守护进程中,这些守护进程需要针对某些内核事件采取行动。此类守护进程通常会维护一个订阅了某个多播组的 Netlink 套接字,内核使用该多播组向感兴趣的用户空间各方通知特定事件。

在这里插入图片描述

由于在任何时候更换用户空间组件时都无需内核察觉,并且具有灵活性,所以相较于直接编址,多播的使用更为可取。

2.2 消息格式

Netlink 协议通常基于消息,由 Netlink 消息头部(struct nlmsghdr)以及附加到它上面的有效载荷组成。有效载荷可以由任意数据构成,但通常包含一个固定大小的特定于协议的头部,其后跟着一系列属性。

在这里插入图片描述

Netlink 消息头部(struct nlmsghdr结构体):

  • 总长度(32 位):消息的总长度,以字节为单位,包括 Netlink 消息头部。

  • 消息类型(16 位):消息类型指定了该消息所携带的有效载荷的类型。Netlink 协议定义了几种标准的消息类型。每个协议族可能会定义额外的消息类型。

  • 消息标志(16 位):消息标志可用于修改消息类型的行为。

  • 序列号(32 位):序列号是可选的,可用于引用先前的消息,例如,一条错误消息可以引用导致该错误的原始请求。

  • 端口号(32 位):端口号指定了该消息应发送到的对等端。如果未指定端口号,该消息将被发送到同一协议族中第一个匹配的内核端套接字。

2.3 消息类型

Netlink 协议区分请求、通知和回复。请求是设置了NLM_F_REQUEST标志的消息,其目的是向接收方请求执行某个操作。请求通常由用户空间进程发送到内核。虽然并非严格强制要求,但每个发送的请求都应该携带一个递增的序列号。

根据请求的性质,接收方可能会用另一条 Netlink 消息来回复该请求。回复的序列号必须与它所关联的请求的序列号相匹配。

通知属于非正规性质的消息,不需要回复,因此序列号通常设置为 0。

在这里插入图片描述

消息的类型主要通过消息头部中设置的 16 位消息类型来识别。定义了以下标准消息类型:

  • NLMSG_NOOP,无操作,该消息必须被丢弃。

  • NLMSG_ERROR,错误消息或确认消息(ACK)。

  • NLMSG_DONE,多部分消息序列的结束。

  • NLMSG_OVERRUN,溢出通知(错误)。

每个 Netlink 协议都可以自由定义自己的消息类型。请注意,小于 NLMSG_MIN_TYPE(0x10)的消息类型值是保留的,不能使用。

通常的做法是使用自定义的消息类型来实现远程过程调用(RPC)模式。假设正在实现的 Netlink 协议的目标是允许对特定网络设备进行配置,因此希望提供对各种配置选项的读写访问权限。实现这一目标的典型 “Netlink 方式” 是定义两种消息类型:MSG_SETCFG(设置配置消息)和 MSG_GETCFG(获取配置消息):

#define MSG_SETCFG      0x11
#define MSG_GETCFG      0x12

发送一条MSG_GETCFG请求消息通常会触发一条消息类型为MSG_SETCFG的回复,回复中包含当前的配置信息。用面向对象的术语来说,这可以描述为 “内核在用户空间中设置配置的本地副本”。

在这里插入图片描述

可以通过发送一条 MSG_SETCFG 消息来更改配置,对该消息的回复要么是一条确认消息(ACK),要么是一条错误消息。

在这里插入图片描述

作为可选操作,内核可以发送配置更改的通知,使用户空间能够监听这些更改,而无需频繁轮询。通知通常会重用现有的消息类型,并且依赖于应用程序使用单独的套接字来区分请求和通知,但你也可以指定一个单独的消息类型。

在这里插入图片描述

尽管从理论上讲,一条 Netlink 消息的大小最大可达 4GiB,但套接字缓冲区很可能不够大,无法容纳如此大小的消息。因此,通常的做法是将消息大小限制为一页的大小(PAGE_SIZE),并使用多部分机制将大块数据分割成几条消息。一条多部分消息(Multipart Messages)设置了标志NLM_F_MULTI,接收方需要持续接收和解析消息,直到接收到特殊的消息类型NLMSG_DONE为止。

与分片的 IP 数据包不同,多部分消息无需重新组装,尽管如果协议希望以这种方式工作,重新组装也是完全可行的。多部分消息常常用于发送对象列表或对象树,每条多部分消息仅仅携带多个对象,从而允许独立解析每条消息。

在这里插入图片描述

错误消息可以作为对请求的响应而发送。错误消息必须使用标准消息类型 NLMSG_ERROR。其有效载荷由一个错误代码和原始请求的 Netlink 消息头部组成。

在这里插入图片描述

错误消息应将序列号设置为导致该错误的请求的序列号。

在这里插入图片描述

确认消息(ACK),发送方可以通过在请求中设置 NLM_F_ACK 标志,来请求接收方为每条已处理的请求发回一条确认消息。这通常用于让发送方在请求被接收方处理之前同步后续的处理操作。

在这里插入图片描述

确认消息也使用消息类型NLMSG_ERROR和有效载荷格式,但错误代码设置为 0。

消息标志,定义了以下标准标志:

#define NLM_F_REQUEST           1
#define NLM_F_MULTI             2
#define NLM_F_ACK               4
#define NLM_F_ECHO              8
  • NLM_F_REQUEST - 消息是一个请求。
  • NLM_F_MULTI - 多部分消息。
  • NLM_F_ACK - 请求确认消息。
  • NLM_F_ECHO - 请求回显该请求。

标志 NLM_F_ECHO 与 NLM_F_ACK 标志类似。它可以与 NLM_F_REQUEST 标志结合使用,使得作为请求结果而发送的通知,无论发送方是否已订阅相应的多播组,都会被发送给发送方。

还定义了一些仅适用于 GET 请求的额外通用消息标志:

#define NLM_F_ROOT      0x100
#define NLM_F_MATCH     0x200
#define NLM_F_ATOMIC    0x400
#define NLM_F_DUMP      (NLM_F_ROOT|NLM_F_MATCH)
  • NLM_F_ROOT - 基于树的根节点返回数据。
  • NLM_F_MATCH - 返回所有匹配的条目。
  • NLM_F_ATOMIC - 已过时,曾经用于请求一个原子操作。
  • NLM_F_DUMP - 返回所有对象的列表(NLM_F_ROOT|NLM_F_MATCH)。

这些标志的使用完全是可选的,许多 Netlink 协议仅使用 NLM_F_DUMP 标志,该标志通常请求接收方以多部分消息序列的形式,发送与消息类型相关的所有对象的列表。

还有另一组与 NEW 或 SET 请求相关的标志。这些标志与 GET 请求的标志相互排斥:

#define NLM_F_REPLACE   0x100
#define NLM_F_EXCL      0x200
#define NLM_F_CREATE    0x400
#define NLM_F_APPEND    0x800
  • NLM_F_REPLACE - 如果对象已存在,则替换该现有对象。
  • NLM_F_EXCL - 如果对象已经存在,则不更新该对象。
  • NLM_F_CREATE - 如果对象尚不存在,则创建该对象。
  • NLM_F_APPEND - 在列表末尾添加对象。

这些标志的行为在不同的 Netlink 协议之间可能会略有不同。

2.4 序列号

Netlink 允许使用序列号来帮助将回复与请求相关联。需要注意的是,与 TCP 等协议不同,Netlink 对序列号没有严格的强制要求。序列号的唯一目的是帮助发送方将回复与相应的请求关联起来。序列号是在每个套接字的基础上进行管理的。

3. Netlink套接字
3.1 Socket实例

为了使用 Netlink 协议,需要一个 Netlink 套接字。每个套接字都定义了一个独立的消息发送和接收上下文。一个应用程序可以使用多个套接字,例如,一个套接字用于发送请求并接收回复,另一个套接字订阅多播组以接收通知。

Netlink 套接字以及所有相关属性(包括实际的文件描述符)都由struct nl_sock结构体表示。

#include <netlink/socket.h>struct nl_sock *nl_socket_alloc(void)
void nl_socket_free(struct nl_sock *sk)

应用程序必须为其希望使用的每个 Netlink 套接字分配一个struct nl_sock结构体的实例。

3.2 序列号

该库会自动为应用程序处理序列号。在套接字结构中存储有一个序列号计数器,当需要发送预期会产生回复(如错误消息或任何其他需要与原始消息相关联的消息类型)的消息时,会自动使用并递增该计数器。

或者,也可以通过函数nl_socket_use_seq()直接使用该计数器。它将返回计数器的当前值,然后将其递增 1。

#include <netlink/socket.h>unsigned int nl_socket_use_seq(struct nl_sock *sk);

不过,大多数应用程序并不希望自己处理序列号。当使用nl_send_auto()函数时,序列号会自动填入,并且在收到回复时会再次进行匹配。

如果所实现的 Netlink 协议不使用请求 / 回复模型,例如当套接字用于接收通知消息时,这种(自动处理序列号的)行为可以并且必须被禁用。

#include <netlink/socket.h>void nl_socket_disable_seq_check(struct nl_sock *sk);
3.3 多播组

每个套接字可以订阅其所连接的 Netlink 协议的任意数量的多播组。然后,该套接字将接收发送到任何一个多播组的每条消息的副本。多播组通常用于实现事件通知。

在内核版本 2.6.14 之前,组订阅是使用位掩码来执行的,这将每个协议族的组数量限制为 32 个。即使不建议在新代码中使用,仍然可以通过函数nl_join_groups()访问这个过时的接口。

#include <netlink/socket.h>void nl_join_groups(struct nl_sock *sk, int bitmask);

从内核版本 2.6.14 开始引入了一种新方法,该方法支持订阅几乎无限数量的多播组。

#include <netlink/socket.h>int nl_socket_add_memberships(struct nl_sock *sk, int group, ...);
int nl_socket_drop_memberships(struct nl_sock *sk, int group, ...);
3.4 回调函数配置

每个套接字都被分配一个回调配置,该配置控制套接字的行为。例如,这对于每个套接字拥有一个单独的消息接收函数是必要的。不过,在套接字之间共享回调配置也是完全可行的。

可以使用以下函数来访问和设置套接字的回调配置:

#include <netlink/socket.h>struct nl_cb *nl_socket_get_cb(const struct nl_sock *sk);
void nl_socket_set_cb(struct nl_sock *sk, struct nl_cb *cb);

此外,还存在一种快捷方式,可以直接修改分配给套接字的回调配置:

#include <netlink/socket.h>int nl_socket_modify_cb(struct nl_sock *sk, enum nl_cb_type type, enum nl_cb_kind kind,nl_recvmsg_msg_cb_t func, void *arg);
3.5 套接字属性

本地端口号唯一标识该套接字,并用于对其进行寻址。在分配套接字时,会自动生成一个唯一的本地端口号。它将由进程 ID(22 位)和一个随机数(10 位)组成,因此每个进程最多允许有 1024 个套接字。

#include <netlink/socket.h>uint32_t nl_socket_get_local_port(const struct nl_sock *sk);
void nl_socket_set_local_port(struct nl_sock *sk, uint32_t port);

注意:可以覆盖本地端口号,但你必须确保所提供的值是唯一的,并且任何其他应用程序中的其他套接字都没有使用相同的值。

可以为套接字分配一个对等端口,这将导致通过该套接字发送的所有单播消息都被发送到该对等方。如果未指定对等方,则消息将发送到内核,内核将尝试自动将该套接字绑定到同一 Netlink 协议族的内核端套接字。通常的做法是不将套接字绑定到对等端口,因为每个 Netlink 协议族通常只存在一个内核端套接字。

#include <netlink/socket.h>uint32_t nl_socket_get_peer_port(const struct nl_sock *sk);
void nl_socket_set_peer_port(struct nl_sock *sk, uint32_t port);

Netlink 使用 BSD 套接字接口,因此每个套接字背后都有一个文件描述符,你可以直接使用它。

#include <netlink/socket.h>int nl_socket_get_fd(const struct nl_sock *sk);

如果一个套接字仅用于接收通知,通常最好将该套接字设置为非阻塞模式,并定期轮询以获取新的通知。

#include <netlink/socket.h>int nl_socket_set_nonblocking(const struct nl_sock *sk);

套接字缓冲区用于在发送方和接收方之间对 Netlink 消息进行排队。这些缓冲区的大小指定了你能够写入 Netlink 套接字的最大大小,也就是说,它将间接定义最大消息大小。默认大小是 32KiB。

#include <netlink/socket.h>int nl_socket_set_buffer_size(struct nl_sock *sk, int rx, int tx);

以下函数允许在套接字上启用 / 禁用自动确认模式。自动确认模式默认是启用的。

#include <netlink/socket.h>void nl_socket_enable_auto_ack(struct nl_sock *sk);
void nl_socket_disable_auto_ack(struct nl_sock *sk);

启用/禁用消息窥探(Message Peeking)。如果启用,消息窥探会使nl_recv函数尝试使用 MSG_PEEK 来检索接收到的下一条消息的大小,并分配一个该大小的缓冲区。消息窥探默认是启用的,但可以使用以下函数将其禁用:

#include <netlink/socket.h>void nl_socket_enable_msg_peek(struct nl_sock *sk);
void nl_socket_disable_msg_peek(struct nl_sock *sk);

启用 / 禁用接收数据包信息。如果启用,从内核接收到的每条 Netlink 消息都将在控制消息中包含一个额外的struct nl_pktinfo结构体。可以使用以下函数来启用 / 禁用接收数据包信息。

#include <netlink/socket.h>int nl_socket_recv_pktinfo(struct nl_sock *sk, int state);

注意,Netlink Pktinfo的处理功能还没有实现。

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

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

相关文章

深入理解TransmittableThreadLocal:原理、使用与避坑指南

一、ThreadLocal与InheritableThreadLocal回顾 在介绍TransmittableThreadLocal之前&#xff0c;我们先回顾一下Java中的ThreadLocal和InheritableThreadLocal。 1. ThreadLocal ThreadLocal提供了线程局部变量&#xff0c;每个线程都可以通过get/set访问自己独立的变量副本…

Linux下的I/O复用技术之epoll

I/O多路复用 指在单个线程或进程中&#xff0c;同时处理多个I/O操作的技术。 旨在提高程序处理多个并发I/O操作的能力&#xff0c;避免程序因等待某个I/O操作而被阻塞。在传统的I/O模型中当程序进行I/O操作时(如读取文件、接受网路数据等)&#xff0c;如果数据还未准备好&…

用 C 语言实现通用的冒泡排序算法

在日常编程中&#xff0c;排序算法是一个非常常见且重要的工具。虽然有许多排序算法可以选择&#xff0c;但如果你需要一个能够处理不同数据类型的排序算法&#xff0c;如何设计一个通用的排序算法呢&#xff1f;今天我们将实现一个通用的冒泡排序算法&#xff0c;支持不同数据…

C# 变量全解析:声明、初始化与使用

在多用途的编程语言中&#xff0c;程序存取数据是一项基础且关键的功能&#xff0c;而这一功能主要通过变量来实现。本文将全面深入地探讨 C# 中的变量&#xff0c;包括变量的种类、声明、初始化、自动初始化、多变量声明以及如何使用变量的值。 变量概述 变量是一个名称&…

Dify中的文本分词处理技术详解

Dify中的文本分词处理技术详解 引言核心架构概览索引处理器工厂 文本分词技术详解基础分词器增强型递归字符分词器固定分隔符文本分词器递归分割算法 索引处理器中的分词应用特殊索引处理器的分词特点问答索引处理器父子索引处理器 分词技术的应用场景技术亮点与优势总结 引言 …

如何打包python程序为可执行文件

将 Python 程序打包为可执行文件是一个常见需求&#xff0c;尤其是在希望将应用程序分享给不具备 Python 环境的用户时。以下是使用 PyInstaller 工具将 Python 程序打包为可执行文件的步骤。 步骤 1&#xff1a;安装 PyInstaller 如果您还没有安装 PyInstaller&#xff0c;请…

美团Java后端二面面经!

场景题是面试的大头&#xff0c;建议好好准备 Q. [美团]如何设计一个外卖订单的并发扣减库存系统&#xff1f; Q.[美团]为啥初始标记和重新标记需要STW&#xff1f; Q.[美团]骑手位置实时更新&#xff0c;如何保证高并发写入&#xff1f; Q.[美团]订单表数据量过大导致查询…

在应用运维过程中,业务数据修改的证据留存和数据留存

在应用运维过程中,业务数据修改的证据留存和数据留存至关重要,以下是相关介绍: 一、证据留存 操作日志记录 : 详细记录每一次业务数据修改的操作日志,包括操作人员、操作时间、修改内容、修改前后数据的对比等。例如,某公司业务系统中,操作日志会精确记录员工小张在 2…

Eigen迭代求解器类

1. 迭代求解器核心类概览 Eigen 提供多种迭代法求解稀疏线性方程组 AxbAxb&#xff0c;适用于大规模稀疏矩阵&#xff1a; 求解器类适用矩阵类型算法关键特性ConjugateGradient对称正定&#xff08;SPD&#xff09;共轭梯度法&#xff08;CG&#xff09;高精度&#xff0c;内…

ORACLE数据库备份入门:第四部分:2-备份场景举例

下面以4个常见的场景为例&#xff0c;介绍如何规划备份方案。备份方案没有标准答案&#xff0c;需要根据实现情况来制定&#xff0c;也和管理员的个人使用习惯有很大相关性。 1 交易型数据库备份 以银行的交易系统为例&#xff0c;除了前一章节提到的关于RPO和RTO的指标外&am…

小白如何学会完整挪用Github项目?(以pix2pix为例)

[目录] 0.如何完整地复现/应用一个Github项目 1.建立适用于项目的环境 2.数据准备与模型训练阶段 3.训练过程中的一些命令行调试必备知识0.如何完整地复现/应用一个Github项目 前日在健身房的组间同一位好友交流时&#xff0c;得到了一个一致结论—— ** Github \texttt{Githu…

蓝桥杯 5. 交换瓶子

交换瓶子 原题目链接 题目描述 有 N 个瓶子&#xff0c;编号为 1 ~ N&#xff0c;放在架子上。 例如有 5 个瓶子&#xff0c;当前排列为&#xff1a; 2 1 3 5 4每次可以拿起 2 个瓶子&#xff0c;交换它们的位置。 要求通过若干次交换&#xff0c;使得瓶子的编号从小到大…

Linux 系统渗透提权

Linux 系统渗透提权 比赛题库-Linux 系统渗透提权 文章目录 Linux 系统渗透提权比赛题库-Linux 系统渗透提权 前言一、解题过程1.使用渗透机对服务器信息收集&#xff0c;并将服务器中 SSH 服务端口号作为 flag 提 交&#xff1b;2.使用渗透机对服务器信息收集&#xff0c;并将…

华为OD机试真题——查找接口成功率最优时间段(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现

2025 A卷 100分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C、GO六种语言的最佳实现方式&#xff1b; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析&#xff1b; 本文收录于专栏&#xff1a;《2025华为OD真题目录…

华为OD机试真题——绘图机器(2025A卷:100分)Java/python/JavaScript/C++/C/GO最佳实现

2025 A卷 100分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析&#xff1b; 并提供Java、python、JavaScript、C、C语言、GO六种语言的最佳实现方式&#xff01; 本文收录于专栏&#xff1a;《2025华为OD真题目录全流程解析/备考攻略/经验…

基于 Python(selenium) 的百度新闻定向爬虫:根据输入的关键词在百度新闻上进行搜索,并爬取新闻详情页的内容

该项目能够根据输入的关键词在百度新闻上进行搜索,并爬取新闻详情页的内容。 一、项目准备 1. 开发环境配置 操作系统:支持 Windows、macOS、Linux 等主流操作系统,本文以 Windows 为例进行说明。Python 版本:建议使用 Python 3.8 及以上版本,以确保代码的兼容性和性能。…

MySQL表的操作 -- 表的增删改查

目录 1. 表的创建2. 表的查看3. 表的修改4. 表的删除5. 总结 1. 表的创建 1.查看字符集及效验规则 2. 表的创建 CREATE TABLE table_name ( field1 datatype, field2 datatype, field3 datatype ) character set 字符集 collate 校验规则 engine 存储引擎;创建用户表1 创建用…

如何解决极狐GitLab 合并冲突?

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 合并冲突 (BASIC ALL) 合并冲突发生在合并请求的两个分支&#xff08;源分支和目标分支&#xff09;对相同代码行进行了不同…

oracle不同数据库版本的自增序列

-- 查看数据库版本 SELECT * FROM v$version WHERE banner LIKE Oracle%; 1. Oracle 12c及以上版本支持 id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, id NUMBER GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1) PRIMARY KEY, -- 语法 id NUMBER GENER…

VIC-3D非接触全场应变测量系统用于小尺寸测量之电子元器件篇—研索仪器DIC数字图像相关技术

在5G通信、新能源汽车电子、高密度集成电路快速迭代的今天&#xff0c;电子元件的尺寸及连接工艺已进入亚毫米级竞争阶段&#xff0c;这种小尺寸下的力学性能评估对测量方式的精度有更高的要求&#xff0c;但传统应变测量手段常因空间尺寸限制及分辨率不足难以捕捉真实形变场。…