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

C实现的双向链表队列

如下代码所示,一个头文件实现的双向链表,用c代码实现:

#ifndef _LINUX_LIST_H
#define _LINUX_LIST_H#include "stddef.h"
#include "poison.h"#ifndef ARCH_HAS_PREFETCH
#define ARCH_HAS_PREFETCH
static inline void prefetch(const void *x) {;}
#endif/** Simple doubly linked list implementation.** Some of the internal functions ("__xxx") are useful when* manipulating whole lists rather than single entries, as* sometimes we already know the next/prev entries and we can* generate better code by using them directly rather than* using the generic single-entry routines.*/struct list_head {struct list_head *next, *prev;
};#define LIST_HEAD_INIT(name) { &(name), &(name) }#define LIST_HEAD(name) \struct list_head name = LIST_HEAD_INIT(name)static inline void INIT_LIST_HEAD(struct list_head *list)
{list->next = list;list->prev = list;
}/** Insert a new entry between two known consecutive entries.** This is only for internal list manipulation where we know* the prev/next entries already!*/
static inline void __list_add(struct list_head *new,struct list_head *prev,struct list_head *next)
{next->prev = new;new->next = next;new->prev = prev;prev->next = new;
}/*** list_add - add a new entry* @new: new entry to be added* @head: list head to add it after** Insert a new entry after the specified head.* This is good for implementing stacks.*/
static inline void list_add(struct list_head *new, struct list_head *head)
{__list_add(new, head, head->next);
}/*** list_add_tail - add a new entry* @new: new entry to be added* @head: list head to add it before** Insert a new entry before the specified head.* This is useful for implementing queues.*/
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{__list_add(new, head->prev, head);
}/** Delete a list entry by making the prev/next entries* point to each other.** This is only for internal list manipulation where we know* the prev/next entries already!*/
static inline void __list_del(struct list_head *prev, struct list_head *next)
{next->prev = prev;prev->next = next;
}/*** list_del - deletes entry from list.* @entry: the element to delete from the list.* Note: list_empty() on entry does not return true after this, the entry is* in an undefined state.*/
static inline void list_del(struct list_head *entry)
{__list_del(entry->prev, entry->next);entry->next = LIST_POISON1;entry->prev = LIST_POISON2;
}/*** list_replace - replace old entry by new one* @old : the element to be replaced* @new : the new element to insert** If @old was empty, it will be overwritten.*/
static inline void list_replace(struct list_head *old,struct list_head *new)
{new->next = old->next;new->next->prev = new;new->prev = old->prev;new->prev->next = new;
}static inline void list_replace_init(struct list_head *old,struct list_head *new)
{list_replace(old, new);INIT_LIST_HEAD(old);
}/*** list_del_init - deletes entry from list and reinitialize it.* @entry: the element to delete from the list.*/
static inline void list_del_init(struct list_head *entry)
{__list_del(entry->prev, entry->next);INIT_LIST_HEAD(entry);
}/*** list_move - delete from one list and add as another's head* @list: the entry to move* @head: the head that will precede our entry*/
static inline void list_move(struct list_head *list, struct list_head *head)
{__list_del(list->prev, list->next);list_add(list, head);
}/*** list_move_tail - delete from one list and add as another's tail* @list: the entry to move* @head: the head that will follow our entry*/
static inline void list_move_tail(struct list_head *list,struct list_head *head)
{__list_del(list->prev, list->next);list_add_tail(list, head);
}/*** list_is_last - tests whether @list is the last entry in list @head* @list: the entry to test* @head: the head of the list*/
static inline int list_is_last(const struct list_head *list,const struct list_head *head)
{return list->next == head;
}/*** list_empty - tests whether a list is empty* @head: the list to test.*/
static inline int list_empty(const struct list_head *head)
{return head->next == head;
}/*** list_empty_careful - tests whether a list is empty and not being modified* @head: the list to test** Description:* tests whether a list is empty _and_ checks that no other CPU might be* in the process of modifying either member (next or prev)** NOTE: using list_empty_careful() without synchronization* can only be safe if the only activity that can happen* to the list entry is list_del_init(). Eg. it cannot be used* if another CPU could re-list_add() it.*/
static inline int list_empty_careful(const struct list_head *head)
{struct list_head *next = head->next;return (next == head) && (next == head->prev);
}/*** list_is_singular - tests whether a list has just one entry.* @head: the list to test.*/
static inline int list_is_singular(const struct list_head *head)
{return !list_empty(head) && (head->next == head->prev);
}static inline void __list_cut_position(struct list_head *list,struct list_head *head, struct list_head *entry)
{struct list_head *new_first = entry->next;list->next = head->next;list->next->prev = list;list->prev = entry;entry->next = list;head->next = new_first;new_first->prev = head;
}/*** list_cut_position - cut a list into two* @list: a new list to add all removed entries* @head: a list with entries* @entry: an entry within head, could be the head itself*	and if so we won't cut the list** This helper moves the initial part of @head, up to and* including @entry, from @head to @list. You should* pass on @entry an element you know is on @head. @list* should be an empty list or a list you do not care about* losing its data.**/
static inline void list_cut_position(struct list_head *list,struct list_head *head, struct list_head *entry)
{if (list_empty(head))return;if (list_is_singular(head) &&(head->next != entry && head != entry))return;if (entry == head)INIT_LIST_HEAD(list);else__list_cut_position(list, head, entry);
}static inline void __list_splice(const struct list_head *list,struct list_head *prev,struct list_head *next)
{struct list_head *first = list->next;struct list_head *last = list->prev;first->prev = prev;prev->next = first;last->next = next;next->prev = last;
}/*** list_splice - join two lists, this is designed for stacks* @list: the new list to add.* @head: the place to add it in the first list.*/
static inline void list_splice(const struct list_head *list,struct list_head *head)
{if (!list_empty(list))__list_splice(list, head, head->next);
}/*** list_splice_tail - join two lists, each list being a queue* @list: the new list to add.* @head: the place to add it in the first list.*/
static inline void list_splice_tail(struct list_head *list,struct list_head *head)
{if (!list_empty(list))__list_splice(list, head->prev, head);
}/*** list_splice_init - join two lists and reinitialise the emptied list.* @list: the new list to add.* @head: the place to add it in the first list.** The list at @list is reinitialised*/
static inline void list_splice_init(struct list_head *list,struct list_head *head)
{if (!list_empty(list)) {__list_splice(list, head, head->next);INIT_LIST_HEAD(list);}
}/*** list_splice_tail_init - join two lists and reinitialise the emptied list* @list: the new list to add.* @head: the place to add it in the first list.** Each of the lists is a queue.* The list at @list is reinitialised*/
static inline void list_splice_tail_init(struct list_head *list,struct list_head *head)
{if (!list_empty(list)) {__list_splice(list, head->prev, head);INIT_LIST_HEAD(list);}
}/*** list_entry - get the struct for this entry* @ptr:	the &struct list_head pointer.* @type:	the type of the struct this is embedded in.* @member:	the name of the list_struct within the struct.*/
#define list_entry(ptr, type, member) \container_of(ptr, type, member)/*** list_first_entry - get the first element from a list* @ptr:	the list head to take the element from.* @type:	the type of the struct this is embedded in.* @member:	the name of the list_struct within the struct.** Note, that list is expected to be not empty.*/
#define list_first_entry(ptr, type, member) \list_entry((ptr)->next, type, member)/*** list_for_each	-	iterate over a list* @pos:	the &struct list_head to use as a loop cursor.* @head:	the head for your list.*/
#define list_for_each(pos, head) \for (pos = (head)->next; prefetch(pos->next), pos != (head); \pos = pos->next)/*** __list_for_each	-	iterate over a list* @pos:	the &struct list_head to use as a loop cursor.* @head:	the head for your list.** This variant differs from list_for_each() in that it's the* simplest possible list iteration code, no prefetching is done.* Use this for code that knows the list to be very short (empty* or 1 entry) most of the time.*/
#define __list_for_each(pos, head) \for (pos = (head)->next; pos != (head); pos = pos->next)/*** list_for_each_prev	-	iterate over a list backwards* @pos:	the &struct list_head to use as a loop cursor.* @head:	the head for your list.*/
#define list_for_each_prev(pos, head) \for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \pos = pos->prev)/*** list_for_each_safe - iterate over a list safe against removal of list entry* @pos:	the &struct list_head to use as a loop cursor.* @n:		another &struct list_head to use as temporary storage* @head:	the head for your list.*/
#define list_for_each_safe(pos, n, head) \for (pos = (head)->next, n = pos->next; pos != (head); \pos = n, n = pos->next)/*** list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry* @pos:	the &struct list_head to use as a loop cursor.* @n:		another &struct list_head to use as temporary storage* @head:	the head for your list.*/
#define list_for_each_prev_safe(pos, n, head) \for (pos = (head)->prev, n = pos->prev; \prefetch(pos->prev), pos != (head); \pos = n, n = pos->prev)/*** list_for_each_entry	-	iterate over list of given type* @pos:	the type * to use as a loop cursor.* @head:	the head for your list.* @member:	the name of the list_struct within the struct.*/
#define list_for_each_entry(pos, head, member)				\for (pos = list_entry((head)->next, typeof(*pos), member);	\prefetch(pos->member.next), &pos->member != (head);	\pos = list_entry(pos->member.next, typeof(*pos), member))/*** list_for_each_entry_reverse - iterate backwards over list of given type.* @pos:	the type * to use as a loop cursor.* @head:	the head for your list.* @member:	the name of the list_struct within the struct.*/
#define list_for_each_entry_reverse(pos, head, member)			\for (pos = list_entry((head)->prev, typeof(*pos), member);	\prefetch(pos->member.prev), &pos->member != (head);	\pos = list_entry(pos->member.prev, typeof(*pos), member))/*** list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()* @pos:	the type * to use as a start point* @head:	the head of the list* @member:	the name of the list_struct within the struct.** Prepares a pos entry for use as a start point in list_for_each_entry_continue().*/
#define list_prepare_entry(pos, head, member) \((pos) ? : list_entry(head, typeof(*pos), member))/*** list_for_each_entry_continue - continue iteration over list of given type* @pos:	the type * to use as a loop cursor.* @head:	the head for your list.* @member:	the name of the list_struct within the struct.** Continue to iterate over list of given type, continuing after* the current position.*/
#define list_for_each_entry_continue(pos, head, member) 		\for (pos = list_entry(pos->member.next, typeof(*pos), member);	\prefetch(pos->member.next), &pos->member != (head);	\pos = list_entry(pos->member.next, typeof(*pos), member))/*** list_for_each_entry_continue_reverse - iterate backwards from the given point* @pos:	the type * to use as a loop cursor.* @head:	the head for your list.* @member:	the name of the list_struct within the struct.** Start to iterate over list of given type backwards, continuing after* the current position.*/
#define list_for_each_entry_continue_reverse(pos, head, member)		\for (pos = list_entry(pos->member.prev, typeof(*pos), member);	\prefetch(pos->member.prev), &pos->member != (head);	\pos = list_entry(pos->member.prev, typeof(*pos), member))/*** list_for_each_entry_from - iterate over list of given type from the current point* @pos:	the type * to use as a loop cursor.* @head:	the head for your list.* @member:	the name of the list_struct within the struct.** Iterate over list of given type, continuing from current position.*/
#define list_for_each_entry_from(pos, head, member)			\for (; prefetch(pos->member.next), &pos->member != (head);	\pos = list_entry(pos->member.next, typeof(*pos), member))/*** list_for_each_entry_safe - iterate over list of given type safe against removal of list entry* @pos:	the type * to use as a loop cursor.* @n:		another type * to use as temporary storage* @head:	the head for your list.* @member:	the name of the list_struct within the struct.*/
#define list_for_each_entry_safe(pos, n, head, member)			\for (pos = list_entry((head)->next, typeof(*pos), member),	\n = list_entry(pos->member.next, typeof(*pos), member);	\&pos->member != (head);					\pos = n, n = list_entry(n->member.next, typeof(*n), member))/*** list_for_each_entry_safe_continue* @pos:	the type * to use as a loop cursor.* @n:		another type * to use as temporary storage* @head:	the head for your list.* @member:	the name of the list_struct within the struct.** Iterate over list of given type, continuing after current point,* safe against removal of list entry.*/
#define list_for_each_entry_safe_continue(pos, n, head, member) 		\for (pos = list_entry(pos->member.next, typeof(*pos), member),		\n = list_entry(pos->member.next, typeof(*pos), member);		\&pos->member != (head);						\pos = n, n = list_entry(n->member.next, typeof(*n), member))/*** list_for_each_entry_safe_from* @pos:	the type * to use as a loop cursor.* @n:		another type * to use as temporary storage* @head:	the head for your list.* @member:	the name of the list_struct within the struct.** Iterate over list of given type from current point, safe against* removal of list entry.*/
#define list_for_each_entry_safe_from(pos, n, head, member)			\for (n = list_entry(pos->member.next, typeof(*pos), member);		\&pos->member != (head);						\pos = n, n = list_entry(n->member.next, typeof(*n), member))/*** list_for_each_entry_safe_reverse* @pos:	the type * to use as a loop cursor.* @n:		another type * to use as temporary storage* @head:	the head for your list.* @member:	the name of the list_struct within the struct.** Iterate backwards over list of given type, safe against removal* of list entry.*/
#define list_for_each_entry_safe_reverse(pos, n, head, member)		\for (pos = list_entry((head)->prev, typeof(*pos), member),	\n = list_entry(pos->member.prev, typeof(*pos), member);	\&pos->member != (head);					\pos = n, n = list_entry(n->member.prev, typeof(*n), member))/** Double linked lists with a single pointer list head.* Mostly useful for hash tables where the two pointer list head is* too wasteful.* You lose the ability to access the tail in O(1).*/struct hlist_head {struct hlist_node *first;
};struct hlist_node {struct hlist_node *next, **pprev;
};#define HLIST_HEAD_INIT { .first = NULL }
#define HLIST_HEAD(name) struct hlist_head name = {  .first = NULL }
#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
static inline void INIT_HLIST_NODE(struct hlist_node *h)
{h->next = NULL;h->pprev = NULL;
}static inline int hlist_unhashed(const struct hlist_node *h)
{return !h->pprev;
}static inline int hlist_empty(const struct hlist_head *h)
{return !h->first;
}static inline void __hlist_del(struct hlist_node *n)
{struct hlist_node *next = n->next;struct hlist_node **pprev = n->pprev;*pprev = next;if (next)next->pprev = pprev;
}static inline void hlist_del(struct hlist_node *n)
{__hlist_del(n);n->next = LIST_POISON1;n->pprev = LIST_POISON2;
}static inline void hlist_del_init(struct hlist_node *n)
{if (!hlist_unhashed(n)) {__hlist_del(n);INIT_HLIST_NODE(n);}
}static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
{struct hlist_node *first = h->first;n->next = first;if (first)first->pprev = &n->next;h->first = n;n->pprev = &h->first;
}/* next must be != NULL */
static inline void hlist_add_before(struct hlist_node *n,struct hlist_node *next)
{n->pprev = next->pprev;n->next = next;next->pprev = &n->next;*(n->pprev) = n;
}static inline void hlist_add_after(struct hlist_node *n,struct hlist_node *next)
{next->next = n->next;n->next = next;next->pprev = &n->next;if(next->next)next->next->pprev  = &next->next;
}#define hlist_entry(ptr, type, member) container_of(ptr,type,member)#define hlist_for_each(pos, head) \for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \pos = pos->next)#define hlist_for_each_safe(pos, n, head) \for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \pos = n)/*** hlist_for_each_entry	- iterate over list of given type* @tpos:	the type * to use as a loop cursor.* @pos:	the &struct hlist_node to use as a loop cursor.* @head:	the head for your list.* @member:	the name of the hlist_node within the struct.*/
#define hlist_for_each_entry(tpos, pos, head, member)			 \for (pos = (head)->first;					 \pos && ({ prefetch(pos->next); 1;}) &&			 \({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \pos = pos->next)/*** hlist_for_each_entry_continue - iterate over a hlist continuing after current point* @tpos:	the type * to use as a loop cursor.* @pos:	the &struct hlist_node to use as a loop cursor.* @member:	the name of the hlist_node within the struct.*/
#define hlist_for_each_entry_continue(tpos, pos, member)		 \for (pos = (pos)->next;						 \pos && ({ prefetch(pos->next); 1;}) &&			 \({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \pos = pos->next)/*** hlist_for_each_entry_from - iterate over a hlist continuing from current point* @tpos:	the type * to use as a loop cursor.* @pos:	the &struct hlist_node to use as a loop cursor.* @member:	the name of the hlist_node within the struct.*/
#define hlist_for_each_entry_from(tpos, pos, member)			 \for (; pos && ({ prefetch(pos->next); 1;}) &&			 \({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \pos = pos->next)/*** hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry* @tpos:	the type * to use as a loop cursor.* @pos:	the &struct hlist_node to use as a loop cursor.* @n:		another &struct hlist_node to use as temporary storage* @head:	the head for your list.* @member:	the name of the hlist_node within the struct.*/
#define hlist_for_each_entry_safe(tpos, pos, n, head, member)		 \for (pos = (head)->first;					 \pos && ({ n = pos->next; 1; }) &&				 \({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \pos = n)#endif

相关文章:

C实现的双向链表队列

如下代码所示,一个头文件实现的双向链表,用c代码实现: #ifndef _LINUX_LIST_H #define _LINUX_LIST_H#include "stddef.h" #include "poison.h"#ifndef ARCH_HAS_PREFETCH #define ARCH_HAS_PREFETCH static inline voi…...

自适应中值滤波器的python代码实现-----冈萨雷斯数字图像处理

基本原理: 自适应中值滤波器是一种图像处理技术,用于去除图像中的噪声。其原理是根据像素周围邻域内像素值的特性,动态地选择滤波器的大小和中值滤波的程度。 **邻域选择:**对于每个像素点,选取一个窗口或者邻域&…...

Python作业答疑_6.22~6.25

一、Python 一班 1. 基数分割列表 1.1 问题描述 给定一无序数列,把数列的第一个数字当成基数,让数列中基数小的数字排在数列前面,比基数大的数字排在数列的后面。 1.2 问题示例 如数列:num[4,1,8,3,9,2,10,7]。基数为 4&…...

Uber Go 语言编码规范

uber-go/guide 的中文翻译 English 文档链接 Uber Go 语言编码规范 Uber 是一家美国硅谷的科技公司,也是 Go 语言的早期 adopter。其开源了很多 golang 项目,诸如被 Gopher 圈熟知的 zap、jaeger 等。2018 年年末 Uber 将内部的 Go 风格规范 开源到 G…...

UniRepLKNet:用于音频、视频、点云、时间序列和图像识别的通用感知大内核ConvNet

摘要 https://arxiv.org/abs/2311.15599 大核卷积神经网络(ConvNets)最近受到了广泛的研究关注,但存在两个未解决的关键问题需要进一步研究。(1)现有大核ConvNets的架构在很大程度上遵循传统ConvNets或Transformers的设计原则,而大核ConvNets的架构设计仍未得到充分解决。(2…...

Http协议与Tomcat

HTTP协议 HTTP协议(HyperText Transfer Protocol)即超文本传输协议 ,是TCP/IC网络体系结构应用层的一个客户端-服务端协议,是所有客户端,服务端数据传输的基石(数据传输规则) 特点 ⭐基于TCP协…...

Spring AOP从入门到精通

目录 1. AOP的演化过程 1. 代理模式 2. 动态代理 2.1 JDK动态代理 2.2 Cglib动态代理 3. Spring模式 3.1 ProxyFactory 3.2 ProxyFactoryBean 3.3 AbstractAutoProxyCreator 2. Spring AOP抽象 1. 核心术语 1.1 连接点(JoinPoint) 1.2 切点(Pointcut) 1.3 增强(Ad…...

Tap虚拟网卡

1 概述 Tap设备通常用于虚拟化场景下,其驱动代码位于drivers/net/tun.c,tap与tun复用大部分代码, 注:drivers/net/tap.c并不是tap设备的代码,而是macvtap和ipvtap; 下文中,我们统一称tap&#…...

【数电笔记】53-与非门构成的基本RS触发器

目录 说明: 1. 电路组成 2. 逻辑功能 3. 特性表 4. 特性方程 5. 状态转换图 6. 驱动表 7. 例题 例1 例2 说明: 笔记配套视频来源:B站;本系列笔记并未记录所有章节,只对个人认为重要章节做了笔记&#xff1b…...

kubernetes(k8s)容器内无法连接同所绑定的Service ClusterIP问题记录

kubernetes(k8s)容器内无法连接同所绑定的Service ClusterIP问题记录 1. k8s环境 k8s使用kubernetes-server-linux-amd64_1.19.10.tar.gz 二进制bin 的方式手动部署 k8s 版本: [rootmaster ~]# kubectl version Client Version: version.Info{Major:"1", Minor:&…...

Hadoop入门学习笔记

视频课程地址:https://www.bilibili.com/video/BV1WY4y197g7 课程资料链接:https://pan.baidu.com/s/15KpnWeKpvExpKmOC8xjmtQ?pwd5ay8 这里写目录标题 一、VMware准备Linux虚拟机1.1. VMware安装Linux虚拟机1.1.1. 修改虚拟机子网IP和网关1.1.2. 安装…...

堆栈,BSS,DATA,TEXT

一、目标文件 首先目标文件的构成,Linux下就是.o 文件 编译器编译源码后生成的文件叫目标文件(Object File)。 目标文件和可执行文件一般采用同一种格式,这种存储格式为 ELF。 目前文件的内容至少有编译后的机器指令代码和数据&a…...

Java八股文面试全套真题【含答案】-JSON篇

什么是JSON? 答案:JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,基于JavaScript的对象字面量表示法,用于在不同语言和平台之间传输数据。JSON的数据结构是怎样的? 答案&#xf…...

数据库管理-第119期 记一次迁移和性能优化(202301130)

数据库管理-第119期 记一次迁移和性能优化(202301130) 1 迁移 之前因为DV组件没有迁移成功的那个PDB,后来想着在目标端安装DV组件迁移,结果目标端装不上,而且开了SR也没看出个所以然来。只能换一个方向,尝…...

【云原生-K8s】镜像漏洞安全扫描工具Trivy部署及使用

基础介绍基础描述Trivy特点 部署在线下载百度网盘下载安装 使用扫描nginx镜像扫描结果解析json格式输出 总结 基础介绍 基础描述 Trivy是一个开源的容器镜像漏洞扫描器,可以扫描常见的操作系统和应用程序依赖项的漏洞。它可以与Docker和Kubernetes集成,…...

【Docker】Swarm的ingress网络

Docker Swarm Ingress网络是Docker集群中的一种网络模式,它允许在Swarm集群中运行的服务通过一个公共的入口点进行访问。Ingress网络将外部流量路由到Swarm集群中的适当服务,并提供负载均衡和服务发现功能。 在Docker Swarm中,Ingress网络使…...

gcc安全特性之FORTIFY_SOURCE

GCC 4.0引入了FORTIFY_SOURCE特性,旨在加强程序的安全性,特别是对于字符串和内存操作函数的使用。下面是对FORTIFY_SOURCE机制的深入分析: 1. 功能 FORTIFY_SOURCE旨在检测和防止缓冲区溢出,格式化字符串漏洞以及其他与内存操作…...

【JUC】二十、volatile变量的特点与使用场景

文章目录 1、volatile可见性案例2、线程工作内存与主内存之间的原子操作3、volatile变量不具有原子性案例4、无原子性的原因分析:i5、volatile变量小总结6、重排序7、volatile变量禁重排的案例8、日常使用场景9、总结 volatile变量的特点: 可见性禁重排无…...

软件工程期末复习(2)

学习资料 设计模式与软件体系结构【期末全整理答案】_软件设计模式与体系结构期末考试题_鸽子不二的博客-CSDN博客 软件设计与体系结构(第二版)部分习题_软件设计与体系结构第二版课后答案-CSDN博客 软件体系结构试题库试题和答案 - 豆丁网Docin 软件设计与体系结构复习 - CN…...

[vue3] 使用 vite 创建vue3项目的详细流程

一、vite介绍 Vite(法语意为 “快速的”,发音 /vit/,发音同 “veet”) 是一种新型前端构建工具,能够显著提升前端开发体验(热更新、打包构建速度更快)。 二、使用vite构建项目 【学习指南】学习新技能最…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...

MMaDA: Multimodal Large Diffusion Language Models

CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

Netty从入门到进阶(二)

二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架&#xff0c;用于…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...