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

Java数据结构学习和源码阅读(线性数据结构)

线性数据结构

链表 LinkList

链表的数据结构

一组由节点组成的数据结构,每个元素指向下一个元素,是线性序列。

最简单的链表结构:

  • 数据
  • 指针(存放执行下一个节点的指针)

不适合的场景:

  • 需要循环遍历将导致时间复杂度的提升

链表分类—单向链表

链表结构:

  • 数据
  • 指针 Next(指向下一个节点)

链表分类-双向列表

链表结构:

  • 数据
  • 指针 Next(指向下一个节点)
  • 指针 Prev(指向前一个节点)

链表分类-循环列表

链表结构:

  • 数据
  • 指针 Next(指向下一个节点,最后一个节点指向第一个节点)

实现一个双向链表

实现链表节点:

public class Node<E> {E item;Node<E> prev;Node<E> next;public Node(E item, Node<E> prev, Node<E> next) {this.item = item;this.prev = prev;this.next = next;}
}

在头节点之前插入节点:

void insertNodeBeforeHead(E e){
final Node<E> oldHeadNode=head;
final Node<E> newHeadNode=new Node<E>(e,null,oldHeadNode);head=newHeadNode;if(oldHeadNode==null){// 说明原先链表中没有元素tail=newHeadNode;}else{// 如果有元素,则需要改变头节点的指针指向oldHeadNode.prev=newHeadNode;}size++;}

在尾节点之后插入节点:

void insertNodeAfterTail(E e){
final Node<E> oldTailNode=tail;
final Node<E> newTailNode=new Node<E>(e,oldTailNode,null);tail=newTailNode;if(oldTailNode==null){head=newTailNode;}else{oldTailNode.next=newTailNode;}size++;}

拆除链表:

E unlinkByNode(Node<E> node){
final E element=node.item;
final Node<E> prevNode=node.prev;
final Node<E> nextNode=node.next;// 改变前一个元素的next指针指向的元素if(prevNode==null){// 说明是头节点head=nextNode;}else{prevNode.next=nextNode;node.prev=null;}// 改变后一个元素的prev指针指向的元素if(nextNode==null){// 说明是尾节点,没有下一个元素tail=prevNode;}else{nextNode.prev=prevNode;node.next=null;}size--;node.item=null;return null;}

移除元素:

 public boolean removeNodeByElement(E e){if(e==null){for(Node<E> start=head;start!=null;start=start.next){if(start.item==null){unlinkByNode(start);return true;}}}else{for(Node<E> start=head;start!=null;start=start.next){if(start.item.equals(e)){unlinkByNode(start);return true;}}}return false;}

LinkedList 源码解读

继承关系

在这里插入图片描述

关键属性

    transient int size=0;/*** Pointer to first node.* Invariant: (first == null && last == null) ||*            (first.prev == null && first.item != null)*/
transient Node<E> first;/*** Pointer to last node.* Invariant: (first == null && last == null) ||*            (last.next == null && last.item != null)*/
transient Node<E> last;

Node

其中节点 Node 的数据结构如下,是 LinkedList 的内部类:

 private static class Node<E> {E item; // 存储数据Node<E> next; // 指向下一个节点Node<E> prev; // 指向前一个节点Node(Node<E> prev, E element, Node<E> next) {this.item = element;this.next = next;this.prev = prev;}
}

transient 的作用

首先,需要理解 Java 中序列化和反序列化的作用:

  • 序列化:将内存中的对象信息转化为二进制数组的方法,可以将数组保存和传输,然后使用原来的类模板恢复对象的信息。
  • 反序列化:使用原来的类模板将序列化后的二进制数组恢复为 Java 对象。

如何实现序列化和反序列化:

  • 实现 Serializable 接口:
    • 写对象信息:ObjectOutputStream.writeObject(Object object),该方法会判断 object 是否重写了 writeObject
      方法,如果重写了,则通过反射调用重写后的方法,完成序列化
    • 读对象信息:ObjectInputStream.readObject()

什么情况下不需要序列化:

  • 节省空间,去除部分无用的属性
  • 持有对象的引用(对象在内存中的地址值)

LinkedList 将 first 和 last 修饰成 transient 的原因:

  • 节省空间
  • 重新连接链表:结点中保存前驱和后继的引用,序列化之后前序结点和后继结点的地址发生了改变,需要连接新的节点。

writeObject && readObject

LinkedList 重写了 writeObject 和 readObject 方法,自定义了序列化和反序列化的过程,用于重新链接节点:

序列化:writeObject


/*** Saves the state of this {@code LinkedList} instance to a stream* (that is, serializes it).** @serialData The size of the list (the number of elements it*             contains) is emitted (int), followed by all of its*             elements (each an Object) in the proper order.*/
private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException{// Write out any hidden serialization magic 调用默认的序列化方法s.defaultWriteObject();// Write out size 指定序列化的容量,单位:32 bit ints.writeInt(size);// Write out all elements in the proper order.// 只把结点中的值序列化,前序和后继的引用不序列化for(Node<E> x=first;x!=null;x=x.next)s.writeObject(x.item);}

反序列化:readObject

/*** Reconstitutes this {@code LinkedList} instance from a stream* (that is, deserializes it).*/
@SuppressWarnings("unchecked")
private void readObject(java.io.ObjectInputStream s)throws java.io.IOException,ClassNotFoundException{// Read in any hidden serialization magic 用默认的反序列化方法s.defaultReadObject();// Read in size 指定读的容量int size=s.readInt();// Read in all elements in the proper order.// 读取每一个结点保存的值,创建新结点,重新连接链表。for(int i=0;i<size; i++)linkLast((E)s.readObject()); // linkLast是向链表中的尾部插入节点的方法}

向链表的最后一个节点插入元素值为 e 的节点:linkLast(E e)

核心流程:

  • 拿到当前的尾节点,记为 l
  • 使用需要创建的元素 e 创建一个新的节点 newNode,prev 属性为 l 节点,next 属性为 null
  • 将当前尾节点设置为上面新创建的节点 newNode
  • 如果 l 节点为空则代表当前链表为空, 将 newNode 设置为头结点,否则将 l 节点的 next 属性设置为 newNode
    /*** Links e as last element.*/void linkLast(E e){
final Node<E> l=last;
final Node<E> newNode=new Node<>(l,e,null);last=newNode;if(l==null)first=newNode;elsel.next=newNode;size++;modCount++;}

向指定节点前插入元素值为 e 的节点: linkBefore(E e, Node succ)

核心流程:

  • 拿到 succ 节点的 prev 节点
  • 使用 e 创建一个新的节点 newNode,其中 prev 属性为 pred 节点,next 属性为 succ 节点
  • 将 succ 节点的 prev 属性设置为 newNode
  • 如果 pred 节点为 null,则代表 succ 节点为头结点,要把 e 插入 succ 前面,因此将 first 设置为 newNode,否则将 pred 节点的 next 属性设为 newNode
    /*** Inserts element e before non-null Node succ.*/void linkBefore(E e,Node<E> succ){
// assert succ != null;
final Node<E> pred=succ.prev;
final Node<E> newNode=new Node<>(pred,e,succ);succ.prev=newNode;if(pred==null)first=newNode;elsepred.next=newNode;size++;modCount++;}

移除链接上的节点 x(取消链接 x):E unlink(Node x)

核心流程:

  • 定义 element 为 x 节点的值,next 为 x 节点的下一个节点,prev 为 x 节点的上一个节点
  • 如果 prev 为空,则代表 x 节点为头结点,则将 first 指向 next 即可;否则,x 节点不为头结点,将 prev 节点的 next 属性指向 x 节点的 next 属性,并将 x 的 prev 属性清空
  • 如果 next 为空,则代表 x 节点为尾节点,则将 last 指向 prev 即可;否则,x 节点不为尾节点,将 next 节点的 prev 属性指向 x 节点的 prev 属性,并将 x 的 next 属性清空
  • 将 x 的 item 属性清空,以便垃圾收集器回收 x 对象
    /*** Unlinks non-null node x.*/E unlink(Node<E> x){
// assert x != null;
final E element=x.item;
final Node<E> next=x.next;
final Node<E> prev=x.prev;if(prev==null){first=next;}else{prev.next=next;x.prev=null;}if(next==null){last=prev;}else{next.prev=prev;x.next=null;}x.item=null;size--;modCount++;return element;}

插入元素:add

默认插入方法,尾部插入:boolean add(E e)

直接插入链表尾部

    /*** Appends the specified element to the end of this list.** <p>This method is equivalent to {@link #addLast}.** @param e element to be appended to this list* @return {@code true} (as specified by {@link Collection#add})*/
public boolean add(E e){linkLast(e);return true;}

指定位置插入元素:add(int index,E element)

流程:

  • 检查索引 index 是否越界(只要用到了索引 index,都会判断是否越界)
  • 如果索引 index 和链表当前的长度 size 相同,则执行尾部插入
  • 否则,将 element 插入原 index 位置节点的前面
    /*** Inserts the specified element at the specified position in this list.* Shifts the element currently at that position (if any) and any* subsequent elements to the right (adds one to their indices).** @param index index at which the specified element is to be inserted* @param element element to be inserted* @throws IndexOutOfBoundsException {@inheritDoc}*/
public void add(int index,E element){checkPositionIndex(index);if(index==size)linkLast(element);elselinkBefore(element,node(index));}

获取节点:get

核心流程:

  • 根据 index,调用 node 方法,寻找目标节点,返回目标节点的 item。
    /*** Returns the element at the specified position in this list.** @param index index of the element to return* @return the element at the specified position in this list* @throws IndexOutOfBoundsException {@inheritDoc}*/
public E get(int index){checkElementIndex(index);return node(index).item;}

根据指定索引 index 位置查找节点

核心流程:

  • 如果 index 的长度是链表长度的一半,则在链表前半部分,从头节点开始遍历
  • 否则,从尾节点开始遍历
    /*** Returns the (non-null) Node at the specified element index.*/Node<E> node(int index){// assert isElementIndex(index);if(index< (size>>1)){Node<E> x=first;for(int i=0;i<index; i++)x=x.next;return x;}else{Node<E> x=last;for(int i=size-1;i>index;i--)x=x.prev;return x;}}

替换指定位置的元素:set

核心流程:

  • 调用 node 方法寻找到目标节点
  • 将目标节点的 item 属性,替换为目标元素
    /*** Replaces the element at the specified position in this list with the* specified element.** @param index index of the element to replace* @param element element to be stored at the specified position* @return the element previously at the specified position* @throws IndexOutOfBoundsException {@inheritDoc}*/
public E set(int index,E element){checkElementIndex(index);Node<E> x=node(index);E oldVal=x.item;x.item=element;return oldVal;}

移除节点

移除指定元素的节点:boolean remove(Object o)

核心流程:

  • 因为普通元素值和 null 判断存在区别,所以需要判断 o 是否为 null,如果 o 为 null,则遍历链表寻找 item 属性为空的节点,并调用 unlink 方法将该节点移除
  • 否则,遍历链表寻找 item 属性跟 o 相同的节点,并调用 unlink 方法将该节点移除。
    /*** Removes the first occurrence of the specified element from this list,* if it is present.  If this list does not contain the element, it is* unchanged.  More formally, removes the element with the lowest index* {@code i} such that* <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>* (if such an element exists).  Returns {@code true} if this list* contained the specified element (or equivalently, if this list* changed as a result of the call).** @param o element to be removed from this list, if present* @return {@code true} if this list contained the specified element*/
public boolean remove(Object o){if(o==null){for(Node<E> x=first;x!=null;x=x.next){if(x.item==null){unlink(x);return true;}}}else{for(Node<E> x=first;x!=null;x=x.next){if(o.equals(x.item)){unlink(x);return true;}}}return false;}

移除指定索引位置的节点:remove(int index)

核心流程:

  • 调用 unlink 方法,移除 index 位置的节点
    /*** Removes the element at the specified position in this list.  Shifts any* subsequent elements to the left (subtracts one from their indices).* Returns the element that was removed from the list.** @param index the index of the element to be removed* @return the element previously at the specified position* @throws IndexOutOfBoundsException {@inheritDoc}*/
public E remove(int index){checkElementIndex(index);return unlink(node(index));}

清除链表中的所有元素:clear

从 first 节点开始遍历,将所有的节点的 item、next、prev 值设置为 null。

    public void clear(){// Clearing all of the links between nodes is "unnecessary", but:// - helps a generational GC if the discarded nodes inhabit//   more than one generation// - is sure to free memory even if there is a reachable Iteratorfor(Node<E> x=first;x!=null;){Node<E> next=x.next;x.item=null;x.next=null;x.prev=null;x=next;}first=last=null;size=0;modCount++;}

question

  1. 描述链表的数据结构
  2. Java 中的 LinkedList 的数据结构和原理

Node 的源码:

  • 有 Next 指针、Prev 指针,说明是双向链表
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CA2FSkdS-1692608562940)(img/Node源码.png)]

LinkedList 的 linkLast 向尾元素后插入元素的方法源码:

  • 尾元素的 prev 指针没有指向头元素,说明非循环
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FHAQWIqG-1692608562941)(img/LinkLast源码.png)]

结论:非循环双向链表

  1. 链表中数据的插入、删除和获取的时间复杂度分析

获取:O(n)
插入:

  • 有前置节点(头尾插入):O(1)
  • 无前置节点:O(n)
  1. 什么场景下更适合使用链表

在不确定数据量且需要频繁插入和删除操作的场景下。

leetcode 题目

707 设计链表

707 设计链表

相关文章:

Java数据结构学习和源码阅读(线性数据结构)

线性数据结构 链表 LinkList 链表的数据结构 一组由节点组成的数据结构&#xff0c;每个元素指向下一个元素&#xff0c;是线性序列。 最简单的链表结构&#xff1a; 数据指针&#xff08;存放执行下一个节点的指针&#xff09; 不适合的场景&#xff1a; 需要循环遍历将…...

华为网络篇 多区域OSPF-32

难度2复杂度2 目录 一、实验原理 二、实验拓扑 三、实验步骤 四、实验过程 总结 一、实验原理 OSPF是一种具有区域概念的路由协议&#xff0c;为什么需要分区域&#xff1f;像RIP那样都在一个区域配置也不多这样简单点不是更好吗&#xff1f;OSPF它是一种功能十分强大的IG…...

【HCIP】03.VLAN高级技术

Eth-trunk 链路聚合&#xff0c;定义出一个逻辑聚合口&#xff0c;把物理接口和逻辑接口关联&#xff0c;此时在STP中&#xff0c;会把多个物理接口看成一个逻辑接口&#xff0c;此时不会出现环路。 接口负载分担&#xff08;逐包|逐流&#xff09; 基于IP的散列算法能保证包…...

WebSocket服务端数据推送及心跳机制(Spring Boot + VUE)

一、WebSocket简介 HTML5规范在传统的web交互基础上为我们带来了众多的新特性&#xff0c;随着web技术被广泛用于web APP的开发&#xff0c;这些新特性得以推广和使用&#xff0c;而websocket作为一种新的web通信技术具有巨大意义。WebSocket是HTML5新增的协议&#xff0c;它的…...

根据Dockerfile创建容器案例讲解

-f为dokerfile的路径&#xff0c; -t为新镜像的名称及版本。 后面这个点是寻址路径。...

CF 1328 D Carousel(环构造)

CF 1328 D. Carousel(环构造) Problem - D - Codeforces 大意&#xff1a;给出一个 n 个数组成的环 &#xff0c; 要对环上的点染色 &#xff0c; 要求任意一个相邻数不同的点对染色不同 &#xff0c;求使用最少的颜色数 &#xff0c; 并用颜色数排列构造一种染色方案。 思路…...

什么是SaaS、PaaS、aPaaS、iPaaS、IaaS,一文讲透

在数字化的带动下&#xff0c;各行业对云服务的需求进入快速增长期。 SaaS、PaaS、aPaaS、iPaaS、IaaS…… 这些词经常出现&#xff0c;那么他们分别是什么意思&#xff1f;又有什么区别&#xff1f;小帆带大家一起来看看~ SaaS SaaS&#xff0c;Software as a Service&…...

Mac nvm 切换为淘宝镜像

编辑环境配置 # 或者 vim ~/.bash_profile $ vim ~/.zshrc贴入镜像 # 淘宝镜像 export NVM_NODEJS_ORG_MIRRORhttp://npm.taobao.org/mirrors/node export NVM_IOJS_ORG_MIRRORhttp://npm.taobao.org/mirrors/iojs# nvm环境配置 export NVM_DIR"$HOME/.nvm"[ -s &quo…...

aardio简单网站css或js下载练习

import win.ui; /*DSG{{*/ var winform win.form(text"下载网站css或js";right664;bottom290;maxfalse) winform.add( buttonClose{cls"button";text"退出";left348;top204;right498;bottom262;color14120960;fontLOGFONT(h-14);note" &qu…...

“维度削减+逻辑回归”:如何使用PCA大幅提升乳腺癌的预测成功率?

一、引言 乳腺癌是女性中最常见的恶性肿瘤之一&#xff0c;也影响着全球范围内许多人们的健康。据世界卫生组织&#xff08;WHO&#xff09;的数据&#xff0c;乳腺癌是全球癌症发病率和死亡率最高的肿瘤之一&#xff0c;其对个体和社会的危害不可忽视。因此&#xff0c;早期乳…...

Python程序设计基础:random库的使用

文章目录 一、常见的random库函数二、应用实例 一、常见的random库函数 在使用Python语言进行编程计算时&#xff0c;计算机完成的计算主要是确定的&#xff0c;但是在将其进行应用时&#xff0c;人们会模拟现实生活中的现象和活动&#xff0c;希望其增加一些随机性&#xff0…...

webpack 打包全流程

目录 1 webpack的安装 2 webpack的配置 配置流程&#xff1a; 1 webpack安装 2 创建webpack配置文件 webpack.config.js 3 配置入口 entry 单入口和多入口 2. 动态配置入口文件 4 配置出口 output 5 配置模式 mode&#xff08;webpack4&#xff09; 6 配置解析策略 …...

如何准备软件开发项目成本估算?

软件开发的成本估算是出了名的困难。对于软件开发项目来说&#xff0c;预算超支反而是常态&#xff0c;而不是例外。 在开始估算之前&#xff0c;请从业务角度了解项目的战略目标和你的目标。你可能计划尽可能赚取更多利润&#xff0c;探索新技术&#xff0c;或者在项目可能亏…...

音视频FAQ(三):音画不同步

摘要 本文介绍了音画不同步问题的五个因素&#xff1a;编码和封装阶段、网络传输阶段、播放器中的处理阶段、源内容产生的问题以及转码和编辑。针对这些因素&#xff0c;提出了相应的解决方案&#xff0c;如使用标准化工具、选择强大的传输协议、自适应缓冲等。此外&#xff0…...

MFC为控件添加背景图片

1、 添加选择Bitmap导入图片&#xff0c;图片文件最好放在项目res目录中&#xff0c;同时是BMP格式。上传后的图片在资源视图&#xff0c;命名为IDB_BITMAP_M_BACK。 2、在cpp的C***Dlg::OnPaint()函数下添加如下代码 void C***Dlg::OnPaint() {CPaintDC dc(this); // device…...

1047:判断能否被3,5,7整除

【题目描述】 给定一个整数&#xff0c;判断它能否被3&#xff0c;5&#xff0c;7整除&#xff0c;并输出以下信息&#xff1a; 1、能同时被3&#xff0c;5&#xff0c;7整除&#xff08;直接输出3 5 7&#xff0c;每个数中间一个空格&#xff09;&#xff1b; 2、只能被其中两…...

十七、DoIP诊断通信 2 (专栏:从零开始搭建一个UDS诊断自动化测试CANoe工程)

专栏:从零开始搭建一个UDS诊断自动化测试CANoe工程 文章目录 专栏:从零开始搭建一个UDS诊断自动化测试CANoe工程前言一、以太网panel面板配置二、DoIP建立连接与断开连接三、panel面板上的DoIP诊断报文发送接收SEND按钮会话切换复位1101按钮解锁按钮DTC按钮3E80保持会话前言 …...

【2023】LeetCode HOT 100——哈希

目录 1. 两数之和1.1 C++实现1.2 Python实现1.3 时空分析2. 字母异位词分组2.1 C++实现2.2 Python实现2.3 时空分析3. 最长连续序列3.1 C++实现3.2 Python实现3.3 时空分析1. 两数之和 🔗 原题链接:1. 两数之和 不妨设 i...

TCP/IP---网络层

一、网络层的主要功能 1、提供了通讯过程中&#xff0c;必须要使用的另一个地址&#xff1a;逻辑IP地址【ipv4、ipv6】 2、连接不同媒介类型【内网--外网&#xff08;intra -- inter&#xff09;】 3、根据运行的不同的路由协议&#xff0c;选择不同的最佳路径 4、在选择的最好…...

解决访问Github出现的Couldn‘t connect to server错误

文章目录 前言原因分析以及解决办法原因分析解决办法 参考 前言 在Github上面克隆代码仓库出现Failed to connect to 127.0.0.1 port 1080 after 2063 ms: Couldnt connect to server、Failed to connect to github.com port 443 after 21083 ms: Couldnt connect to server等…...

善于打仗的人,没有特别大的名气和勇功

善于打仗的人&#xff0c;没有特别大的勇功 【安志强趣讲《孙子兵法》第15讲】 【原文】 见胜不过众人之所知&#xff0c;非善之善者也&#xff1b;战胜而天下曰善&#xff0c;非善之善者也。 【趣讲白话】 预判胜负没有超出常人的见识&#xff0c;算不上高明中最高明的&#x…...

虚幻官方项目《CropOut》技术解析 之 程序化岛屿生成器(IslandGenerator)

开个新坑详细分析一下虚幻官方发布的《CropOut》&#xff0c;文章会同步发布到我在知乎|CSDN的专栏里 文章目录 概要Create Island几何体生成部分随机种子Step 1Step 2Step 3Step 4Step 5Step 6 岛屿材质部分动态为草地设置颜色 程序设计的小技巧其它Platform Switch函数 概要 …...

微服务中间件--微服务保护

微服务保护 微服务保护a.sentinelb.sentinel限流规则1) 流控模式1.a) 关联模式1.b) 链路模式 2) 流控效果2.a) 预热模式2.b) 排队等待 3) 热点参数限流 c.隔离和降级1) Feign整合Sentinel2) 线程隔离2.a) 线程隔离&#xff08;舱壁模式&#xff09; 3) 熔断降级3.a) 熔断策略-慢…...

Excel VBA 复制除指定工作表外所有的工作表的内容到一张工作表中

当我们有一张表里面有很多sheet 具有相同的表结构&#xff0c;如果需要汇总到一张表中&#xff0c;那么我们可以借助VBA 去实现汇总自动化 Sub 复制所有工作表内容()Dim ws As WorksheetDim targetSheet As WorksheetDim lastRow As Long 设置目标表格&#xff0c;即要将所有…...

电脑上安装,多版本node

手上有一个vue3的项目&#xff0c;sass配置如下图所示&#xff1a; 安装了Python3.10和node 16.14.0&#xff0c;项目能正常install 跟run。 因工作需要&#xff0c;收上有一个vue2的项目&#xff0c;sass配置如下图所示&#xff1a; 执行npm intsall 的时候一直报Python2找不…...

「网页开发|环境安装」Windows系统下安装node.js

本文主要介绍在windows系统下的node.js环境安装。windows系统的Node.js安装过程与其他普通软件的安装类似&#xff0c;本文主要给刚入门的伙伴一个参考。 文章目录 场景说明安装步骤下载安装包运行安装程序验证安装添加系统环境变量配置node_cache和node_global变量 场景说明 …...

【腾讯云Cloud Studio实战训练营】用Vue+Vite快速构建完成交互式3D小故事

&#x1f440;前置了解&#xff1a;(官网 https://cloudstudio.net/) 什么是Cloud Studio&#xff1f; Cloud Studio 是基于浏览器的集成式开发环境&#xff08;IDE&#xff09;&#xff0c;为开发者提供了一个永不间断的云端工作站。用户在使用 Cloud Studio 时无需安装&#…...

MySQL和Java中的货币字段类型选择

​ 推荐阅读 AI文本 OCR识别最佳实践 AI Gamma一键生成PPT工具直达链接 玩转cloud Studio 在线编码神器 玩转 GPU AI绘画、AI讲话、翻译,GPU点亮AI想象空间 资源分享 「java、python面试题」来自UC网盘app分享&#xff0c;打开手机app&#xff0c;额外获得1T空间 https:…...

第6步---MySQL的控制流语句和窗口函数

第6步---MySQL的控制流语句和窗口函数 1.IF关键字 -- 控制流语句 SELECT IF(5>3,大于,小于);-- 会单独生成一列的 SELECT *,IF(score >90 , 优秀, 一般) 等级 FROM stu_score;-- IFNULL(expr1,expr2) SELECT id,name ,IFNULL(salary,0),dept_id FROM emp4;-- ISNULL() …...

Android通过OpenCV实现相机标定

在 Android 中使用 OpenCV 实现相机标定&#xff0c;你可以按照以下步骤进行操作&#xff1a; 首先&#xff0c;确保你已经在项目中引入了 OpenCV 库的依赖。 创建一个 CameraCalibrator 类&#xff0c;用于执行相机标定。 import org.opencv.calib3d.Calib3dimport org.open…...

我们可能要为ChatGPT的谢幕做好准备

ChatGPT的未来&#xff1a;悬念仍存 ​ 人工智能已经成为我们生活不可或缺的一部分。在众多AI应用中&#xff0c;OpenAI研发的ChatGPT凭借其极强的语言理解和生成能力脱颖而出&#xff0c;是一项划时代的变革性创新&#xff0c;帮助了无数企业和个人&#xff0c;改变了我们与技…...

深入浅出Pytorch函数——torch.nn.init.xavier_normal_

分类目录&#xff1a;《深入浅出Pytorch函数》总目录 相关文章&#xff1a; 深入浅出Pytorch函数——torch.nn.init.calculate_gain 深入浅出Pytorch函数——torch.nn.init.uniform_ 深入浅出Pytorch函数——torch.nn.init.normal_ 深入浅出Pytorch函数——torch.nn.init.c…...

Abandon_Ubuntu Declaration

鉴于以下几个原因&#xff0c;持续到明年考研结束&#xff0c;我将不再捣鼓ubuntu和任何linux系统&#xff0c; 原因如下&#xff1a; ubuntu23.04不支持wps编辑pdf这个核心功能&#xff0c;且开机向canonial公司发送远程遥测&#xff0c;暂时不会用iptables禁用&#xff0c;故…...

Java设计模式-抽象工厂模式

简介 设计模式是软件设计中的一种常见方法&#xff0c;通过定义一系列通用的解决方案&#xff0c;来解决常见的软件设计问题。其中&#xff0c;抽象工厂模式是一种非常常见的设计模式&#xff0c;它可以帮助我们创建一组相关的对象&#xff0c;而不需要指定具体的实现方式。 …...

Rust语法:所有权引用生命周期

文章目录 所有权垃圾回收管理内存手动管理内存Rust的所有权所有权转移函数所有权传递 引用与借用可变与不可变引用 生命周期悬垂引用函数生命周期声明结构体的生命周期声明Rust生命周期的自行推断生命周期约束静态生命周期 所有权 垃圾回收管理内存 Python&#xff0c;Java这…...

办手机卡/流量卡需要问清楚啥?

网上的手机卡一搜能出现千千万&#xff0c;那么怎么才能避免购买到那些套路卡呢&#xff1f;今天就给大家分享一下&#xff0c;办理手机卡时需要问清楚什么&#xff1f; ​ 办理流量卡需要咨询的五大问题&#xff0c;下面开始进入正题。 1、是否是正规号卡&#xff1f;正规的号…...

vim基本使用方法

VIM 1.vim介绍2.vim基本操作2.1 模式切换2.2 命令模式2.3 底行模式 1.vim介绍 vim是linux上一个有多个编辑模式的编辑器。 这里主要介绍三种模式&#xff1a; 命令模式&#xff08;Normal mode&#xff09; 执行命令的模式&#xff0c;主要任务就是控制光标移动、复制和删除。…...

漏洞指北-VulFocus靶场专栏-入门

漏洞指北-VulFocus靶场01-入门 VulFocus靶场前置条件&#xff1a;入门001 命令执行漏洞step1&#xff1a; 输入默认index的提示step2&#xff1a; 入门002 目录浏览漏洞step1&#xff1a;进入默认页面&#xff0c;找到tmp目录step2 进入tmp目录获取flag文件 VulFocus靶场前置条…...

管理类联考——逻辑——真题篇——按知识分类——汇总篇——二、论证逻辑——推论——第二节——数字推理题

文章目录 第二节 数字推理题真题(2017-31)——推论——数字推理题——数量比例模型真题(2014-33)——推论——数字推理题——数量比例模型——(1)若题干既有数量,也有比例,答案一般为数量。(2)若题干只有比例没有数量,答案一般为比例。真题(2018-44)——推论——数…...

git基础教程(24) git reflog查看引用日志

文章目录 1、`git reflog`命令说明2、`git reflog`命令显示内容3、具体的用法4、引起ref变化的操作有git reflog 命令是用来恢复本地错误操作很重要的一个命令,所以在这里对它进行一下整理。 1、git reflog命令说明 reflog翻译:Reference logs(参考日志) git reflog命令:…...

成都爱尔谭娇主任提醒孩子不停揉眼睛是因为什么

孩子总是揉眼睛&#xff0c; 明显眼睛不舒服&#xff0c; 但看着好像没什么? 可孩子不停眨眼流泪&#xff0c; 肯定不对…… 孩子到底怎么了? 孩子可能长了“倒睫”! 孩子出现倒睫毛就是睫毛不朝外长而向内长&#xff0c;是婴幼儿很容易患的一种眼病。 由于孩子的脸颊及鼻梁发…...

医疗设备管理软件哪家好?医院设备全生命周期管理要怎么做?

随着医学技术的不断进步&#xff0c;医疗设备变得越来越先进&#xff0c;越来越复杂。因此&#xff0c;医疗设备的管理也变得越来越重要。传统的医疗设备管理方式存在很多问题&#xff0c;比如设备数据难统计、报修方式难统一、巡检维保难规范等。为了解决这些问题&#xff0c;…...

基于PaddlePaddle实现的声纹识别系统

前言 本项目使用了EcapaTdnn、ResNetSE、ERes2Net、CAM等多种先进的声纹识别模型&#xff0c;不排除以后会支持更多模型&#xff0c;同时本项目也支持了MelSpectrogram、Spectrogram、MFCC、Fbank等多种数据预处理方法&#xff0c;使用了ArcFace Loss&#xff0c;ArcFace loss…...

使用GDB工具分析core文件的方法

引言&#xff1a; 在软件开发过程中&#xff0c;我们经常会遇到程序崩溃或异常退出的情况。这时&#xff0c;一个非常有用的工具就是GDB&#xff08;GNU调试器&#xff09;&#xff0c;它可以帮助我们分析core文件并找出导致程序崩溃的原因。本文将介绍如何使用GDB工具来分析c…...

Maven - 统一构建规范:Maven 插件管理最佳实践

文章目录 Available Plugins开源项目中的使用插件介绍maven-jar-pluginmaven-assembly-pluginmaven-shade-pluginShade 插件 - 标签artifactSetrelocationsfilters 完整配置 Available Plugins https://maven.apache.org/plugins/index.html Maven 是一个开源的软件构建工具&…...

对接海康明眸门禁设备-删除人员信息

对接海康明眸门禁设备-删除人员信息 文中登录 退出登录 长连接和海康hCNetSDK等接口 见文章 初始SDK和登录 /*** 删除人脸 IotCommDataResult 自定义类 收集结果*/Overridepublic List<IotCommDataResult> deleteFace(IotCameraParam camera, Collection<Long> us…...

LEADTOOLS Imaging SDK Crack

LEADTOOLS Imaging SDK Crack 高级开发人员工具包包括ActiveX和WPF/XAML控件。 LEADTOOLS Imaging SDK为文件格式导入/导出、图像压缩、图像显示和效果、颜色转换、图像处理、TWAIN扫描、图像通用对话框、数据库集成、打印和互联网提供了基本和高级的彩色图像功能。 LEADTOOLS …...

2023并发之八股文——面试题

基础知识 并发编程的优缺点为什么要使用并发编程&#xff08;并发编程的优点&#xff09; 充分利用多核CPU的计算能力&#xff1a;通过并发编程的形式可以将多核CPU 的计算能力发挥到极致&#xff0c;性能得到提升方便进行业务拆分&#xff0c;提升系统并发能力和性能&#x…...

操作记录日志保存设计实现

定义一个切面类 @Aspect @Slf4j @Component @RequiredArgsConstructor public class OperateLogAopConfig {private final ISysOperateLogService sysOperateLogService;@Around("@annotation(operateLog)")public Object operateLog(ProceedingJoinPoint point, Op…...

PL 侧驱动和fpga 重加载的方法

可以解决很多的问题 时钟稳定后加载特定fpga ip &#xff08;要不内核崩的一塌糊涂&#xff09;fpga 稳定复位软件决定fpga ip 加载的时序 dluash load /usr/local/scripts/si5512_setup.lua usleep 30 mkdir -p /lib/firmware cp -rf /usr/local/firmare/{*.bit.bin,*.dtbo} …...