【数据结构】(6) LinkedList 链表
一、什么是链表
1、链表与顺序表对比
不同点 | LinkedList | ArrayList |
物理存储上 | 不连续 | 连续 |
随机访问效率 | O(N) | O(1) |
插入、删除效率 | O(1) | O(N) |
3、链表的分类
链表根据结构分类,可分为单向/双向、无头结点/有头节点、非循环/循环链表,这三组每组各取一个就构成一种结构链表。其中,单向、不带头、非循环链表是学习的重点;双向、不带头、非循环链表在实际开发中常用。
以单向、不带头、非循环链表为例:
双向、不带头、非循环链表:
单向、带头、非循环链表(好处在于,不用特别处理头节点,比如增删时):
单向、不带头、循环链表:
二、单向、不带头、非循环链表的实现
1、IList 接口
定义 IList 接口,声明线性表需要实现的方法:
package listinterface;public interface IList {//头插法void addFirst(int data);//尾插法void addLast(int data);//任意位置插入,第一个数据节点为0号下标void addIndex(int index,int data);//查找是否包含关键字key是否在单链表当中boolean contains(int key);//删除第一次出现关键字为key的节点void remove(int key);//删除所有值为key的节点void removeAllKey(int key);//得到单链表的长度int size();void clear();void display();
}
2、结点内部类
结点仅由链表内部使用,且每个结点的产生不依赖于某个链表,可定义为链表的私有静态内部类:
public class MySingleList implements IList {// 结点内部类private static class Node {int data;Node next;public Node(int data) {this.data = data;}}// 头结点private Node head;// 链表长度private int size;............
}
3、打印链表
@Overridepublic void display() {Node cur = head;while (cur != null) {System.out.print(cur.data + " ");cur = cur.next;}System.out.println(" size: " + size);}
4、清空链表、获取链表长度
@Overridepublic int size() {return size;}@Overridepublic void clear() {head = null;size = 0;}
head 为空,没有引用指向 node1,自动回收 node1;node1 回收,没有引用指向 node2,自动回收 node2……故 clear 只需 head 设为 null 即可。
5、头插法
@Overridepublic void addFirst(int data) {Node newNode = new Node(data);newNode.next = head;head = newNode;
// if (head != null) {
// newNode.next = head;
// }
// head = newNode;size++;}
6、尾插法
@Overridepublic void addLast(int data) {Node newNode = new Node(data);if (head == null) {head = newNode;size++;return;}Node cur = head;while (cur.next != null) { // 找到尾节点cur = cur.next;}cur.next = newNode;size++;}
7、任意位置插入
(受查异常,父类方法没抛出异常,子类方法不能抛出异常;父类抛出了,子类不做要求。非受查异常,不做要求。)为了不改动 IList,且让 addIndex 抛出异常,以便在 main 处对异常做处理,链表下标越界异常选择继承非受查异常 RuntimeExcption。
package myexception;public class ListIndexOutOfBoundsException extends RuntimeException {public ListIndexOutOfBoundsException(String message) {super(message);}
}
private void checkIndexOutOfBounds(int index) throws ListIndexOutOfBoundsException {if (index < 0 || index > size) {throw new ListIndexOutOfBoundsException("插入位置不合法。" + "Index: " + index + ", Size: " + size);}}private Node findIndex(int index) {Node cur = head;int cnt = 0;while (cnt != index) {cur = cur.next;cnt++;}return cur;}@Overridepublic void addIndex(int index, int data) throws ListIndexOutOfBoundsException {// 先检查索引是否越界checkIndexOutOfBounds(index);if (index == 0) { // 在 0 处插入,没有前驱节点addFirst(data);return;}if (index == size) { // 在末尾插入addLast(data);return;}Node newNode = new Node(data);// 找到插入位置前的节点Node pre = findIndex(index - 1);// 插入新节点newNode.next = pre.next;pre.next = newNode;size++;}
8、删除第一次出现关键字为key的节点
private Node findKey(int key) {Node cur = head;while (cur.next != null) {if (cur.next.data == key) {return cur;}cur = cur.next;}return null;}@Overridepublic void remove(int key) {if (head == null) { // 空链表return;}if (head.data == key) { // 头节点就是要删除的节点head = head.next;size--;return;}Node pre = findKey(key);if (pre != null) { // 找到了要删除的节点pre.next = pre.next.next;size--;} else { // 要删除的节点不存在System.out.println("要删除的节点不存在。");}}
9、删除所有关键字为 key 的节点
@Overridepublic void removeAllKey(int key) {if (head == null) { // 空链表return;}Node pre = head;Node cur = head.next;while (cur != null) {if(cur.data == key) {pre.next = cur.next;// cur = cur.next;}else {pre = cur;// cur = cur.next;}cur = cur.next;}if (head.data == key) {head = head.next;size--;}}
三、链表面试题练习
1、反转链表
206. 反转链表 - 力扣(LeetCode)
思路:从头开始,边遍历边反转,最后尾结点为 head。
class Solution {public ListNode reverseList(ListNode head) {// 特殊处理 空链表、只有一个结点的链表if(head == null || head.next == null) { // 两者顺序不能反,因为 null 没有nextreturn head;}ListNode cur = head.next;// 头结点,其 next 为 null head.next = null;// 边反转边遍历,直到反转完尾结点while(cur != null) {ListNode curN = cur.next; cur.next = head;head = cur;cur = curN;}return head;}
}
2、链表的中间结点
876. 链表的中间结点 - 力扣(LeetCode)
思路:
1、计算链表长度的一半,再走一半长。时间复杂度 O(N) + O(N/2)。
2、设置 slow 和 fast 从 head 开始走,slow 每次走 1 步,fast 每次走 2 步。那么 fast 走完全程(fast = null 或者 fast.next = null),必是 slow 的两倍长度,故 slow 就是中间节点的位置。时间复杂度 O(N/2) ,更优。
class Solution {public ListNode middleNode(ListNode head) { // 根据题目,链表非空// 从头节点开始ListNode slow = head;ListNode fast = head;// fast 走完整个链表while(fast != null && fast.next != null) {// slow 每次走 1 步,fast 每次走 2 步slow = slow.next;fast = fast.next.next;}// slow 就是中间结点return slow;}
}
3、返回倒数第 k 个结点
面试题 02.02. 返回倒数第 k 个节点 - 力扣(LeetCode)
思路:slow 从 head 开始,fast 比 slow 先多走 k-1 步,然后 slow、fast 每次只走一步,直到 fast 走到尾结点。
class Solution {public int kthToLast(ListNode head, int k) {// 根据题目,k 保证有效,因此不用判断 k<=0 和 k > len 的情况ListNode slow = head;ListNode fast = head;// 当 fast 先走 k-1 步int cnt = k-1;// k保证有效,fast 不会走过头while(cnt != 0) { fast = fast.next;cnt--;}// 让 fast 走到尾结点,slow 就是倒数第 k 个结点while(fast.next != null) {slow = slow.next;fast = fast.next;}return slow.val;}
}
4、合并两个有序列表
21. 合并两个有序链表 - 力扣(LeetCode)
思路:分别同时遍历两个链表,更小的插入新链表,插入的链表插入后更新为 next,直到 l1 或者 l2 遍历完了。没遍历完的那个链表,把剩的接在新链表尾。为了不单独处理头指针,新链表带头节点。
class Solution {public ListNode mergeTwoLists(ListNode list1, ListNode list2) {ListNode head = new ListNode(); // 创建头节点ListNode cur = head;ListNode cur1 = list1;ListNode cur2 = list2;// 其中一个遍历完就退出while(cur1 != null && cur2 != null) {if(cur1.val < cur2.val) {cur.next = cur1;// cur = cur.next;cur1 = cur1.next;}else {cur.next = cur2;// cur = cur.next;cur2 = cur2.next;}cur = cur.next;}// 没遍历完的,接在后面if(cur1 != null) {cur.next = cur1;}if(cur2 != null) {cur.next = cur2;}return head.next; // 不带头节点}
}
5、链表分割
链表分割_牛客题霸_牛客网
思路:先创建两个链表,依次遍历原链表,小于和大于等于 x 的分开尾插入两个链表,再合并。
public class Partition {public ListNode partition(ListNode pHead, int x) {// 创建两个头节点ListNode head1 = new ListNode(-1); ListNode head2 = new ListNode(-1);// 遍历原链表,每个结点与 x 比大小,分类放在两个新链表中ListNode cur1 = head1;ListNode cur2 = head2; while(pHead != null) {if(pHead.val < x) {cur1.next = pHead;cur1 = cur1.next;}else {cur2.next = pHead;cur2 = cur2.next;}pHead = pHead.next;}// 现在 cur1、cur2 分别指向两个链表的尾结点。cur1.next = head2.next; // 链表1的尾接上链表2的头cur2.next = null; // 链表2的尾接上 null// 如果最后链表1为空,cur1就是head1,没问题// 如果最后链表2为空,cur2就是head2,没问题return head1.next;}
}
6、链表的回文结构
链表的回文结构_牛客题霸_牛客网
思路:
1、求尾结点,头、尾同时前进并比较,到 head = tail(奇数长度) 或者 head.next = tail (偶数长度)为止。tail 往前走行不通,因为是单链表。
2、把原链表的后一半反转,再将反转链表与原链表对比,直到反转链表遍历完。时间复杂度O(N/2)+O(N/2)+O(N/2)=O(N)。找到一半处、将一半反转、对比一半。
public class PalindromeList {private ListNode findHalf(ListNode head) {ListNode slow = head;ListNode fast = head;while(fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;}return slow;}private ListNode reverse(ListNode head) {if(head == null || head.next == null) {return head;}ListNode cur = head.next;head.next = null;while(cur != null) {ListNode curN = cur.next;cur.next = head;head = cur;cur = curN;}return head;}public boolean chkPalindrome(ListNode A) {// 找到中间结点ListNode halfNode = findHalf(A);// 将后一半反转ListNode B = reverse(halfNode);// 将后半段与前半段对比,后半段遍历完退出while(B != null) {if(A.val != B.val) {return false;}A = A.next;B = B.next;}return true;}
}
7、相交链表
160. 相交链表 - 力扣(LeetCode)
思路:可能分叉的地方,前边或后边。但是对于链表不可能后边分叉,因为如果后边分叉了,当你遍历一条单链时,遍历到后边分叉的地方,就不知道继续走哪条路了,这样就不是单链表了。因此只有可能如上图的Y型,或者在一条直线上。
如果同时各自出发,每次走一步,直到有一方到达尾结点,那么短的链表总是先到达,并且它们的最终距离是两链表的长度差。长度差来自分叉的部分,而不是相交的部分。那么如果让长的先走长度差步,再同时走,它们碰面的地方将是相交处。
public class Solution {private int size(ListNode head) {ListNode cur = head;int cnt = 0;while(cur != null) {cnt++;cur = cur.next;}return cnt;}public ListNode getIntersectionNode(ListNode headA, ListNode headB) {// 求两条链的长度int size1 = size(headA);int size2 = size(headB);// 让长的作为 headA,求两链表长度差(正),int len = size1 - size2;if(size1 < size2) {len = size2 - size1;ListNode tmp = headA;headA = headB;headB = tmp;}// 让长的先走 len 步while(len != 0) {headA = headA.next;len--;}// 再同时走,相等的地方就是相交结点while(headA != headB) {headA = headA.next;headB = headB.next;}return headA;}
}
8、环形链表
141. 环形链表 - 力扣(LeetCode)
思路:慢指针和快指针同时走,如果有环,那么快、慢指针总会在环里相遇(快指针多跑 k 圈,然后追上慢指针);如果没环,快指针先走完全程结束。我们设慢指针每次走1步,快指针每次走2步。
为什么快指针不能是 3、4、……、n 步?如果是3步,存在以下情况,无论走多久都不会相遇:
快指针如果走 4 步,存在以下情况,无论走多久都不会相遇:
以此类推……
public class Solution {public boolean hasCycle(ListNode head) {// 设置快、慢指针ListNode slow = head;ListNode fast = head;// slow 每次走1步,fast 每次走2步// 直到 fast = null(偶数个) 或者 fast.next = null(奇数个) 返回 flase// 或者 slow = fast 返回 truewhile(fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;if(slow == fast) {return true;}}return false;}
}
9、环形链表Ⅱ
142. 环形链表 II - 力扣(LeetCode)
思路:
若一指针 head1 从相遇点开始,一指针 head2 从头指针开始,同时走,每次走一步。当 head1 走 X 步到达入口;同时,head2 从相遇点开始走了 (k-1) 圈回到相遇点,再走 N 步到入口。即两指针相遇处,就是入口结点。
public class Solution {private ListNode getMeetNode(ListNode head) {ListNode slow = head;ListNode fast = head;while(fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;if(slow == fast) {return slow;}}return null;}public ListNode detectCycle(ListNode head) {// 获得 slow 与 fast 的相遇结点ListNode meetNode = getMeetNode(head);// 链表无环,返回 nullif(meetNode == null) {return null;}// 分别从头指针,相遇结点开始走,两指针相遇处就是入口while(head != meetNode) {head = head.next;meetNode = meetNode.next;}return head;}
}
四、双向、不带头、非循环链表的实现
1、Node 内部类和属性
public class MyLinkedList implements IList {private static class Node {int val;Node next; // 后继指针Node prev; // 前驱指针public Node(int val) {this.val = val;}}private Node head; // 头指针private Node tail; // 尾指针private int size; // 链表大小............
}
2、清空链表
与单向不同直接 head = null,双向需要遍历结点并释放 node,原因如下:head 为空,还有 node2 指向 node1,所以手动置 node2 的 pre 为空,node1释放;还有 node3 指向 node2,手动置 node3 的 pre 未空……
@Overridepublic void clear() {Node cur = head;while (cur!= null) {Node curN = cur.next;cur.prev = null;cur.next = null;cur = curN;}head = null;tail = null;size = 0;}
3、头插法
@Overridepublic void addFirst(int data) {Node newNode = new Node(data);if (head == null) {head = newNode;tail = newNode;} else {newNode.next = head;head.prev = newNode;head = newNode;}size++;}
4、尾插法
@Overridepublic void addLast(int data) {Node newNode = new Node(data);if (head == null) {head = newNode;tail = newNode;} else {tail.next = newNode;newNode.prev = tail;tail = newNode;}size++;}
5、任意位置插入
@Overridepublic void addIndex(int index, int data) {// 先检查索引是否越界checkIndexOutOfBounds(index);if (index == 0) { // 在 0 处插入,没有前驱节点addFirst(data);return;}if (index == size) { // 在末尾插入addLast(data);return;}Node newNode = new Node(data);// 找到插入位置Node cur = findIndex(index);// 插入新节点newNode.next = cur;newNode.prev = cur.prev;cur.prev.next = newNode;cur.prev = newNode;size++;}
6、删除第一次出现的 key
private Node findKey(int key) {Node cur = head;while (cur != null) {if (cur.val == key) {return cur;}cur = cur.next;}return null;}@Overridepublic void remove(int key) {Node deleteNode = findKey(key); // 找到待删除节点,如果不存在,返回 nullif (deleteNode == null) { // 包含空链表的情况System.out.println("要删除的节点不存在。");return;}if (deleteNode == head) { // 待删除节点是头节点,包含了链表只有一个结点的情况head = deleteNode.next;if (head == null) { // 链表只有一个节点tail = null;} else {head.prev = null;}} else if (deleteNode == tail) { // 待删除节点是尾节点tail = deleteNode.prev;tail.next = null;} else { // 待删除节点是中间节点deleteNode.prev.next = deleteNode.next;deleteNode.next.prev = deleteNode.prev;}size--;}
7、删除所有 key
@Overridepublic void removeAllKey(int key) {Node cur = head;while (cur != null) {if (cur.val == key) {if (cur == head) { // 待删除节点是头节点head = cur.next;if (head == null) { // 链表中只有一个节点tail = null;}else {head.prev = null;}} else if (cur == tail) { // 待删除节点是尾节点tail = cur.prev;tail.next = null;} else { // 待删除节点是中间节点cur.prev.next = cur.next;cur.next.prev = cur.prev;}size--;
// cur = cur.next; // 跳过已删除节点,继续遍历} /*else {cur = cur.next;}*/cur = cur.next;}}
五、LinkedList 的使用
集合类中,LinkedList 的底层是双向链表。
1、常用方法的使用
2、迭代器
Iterator<E> 是集合类通用的迭代器,线性表专用的迭代器 ListIterator<E> 功能更强,可以反向迭代:
相关文章:
【数据结构】(6) LinkedList 链表
一、什么是链表 1、链表与顺序表对比 不同点LinkedListArrayList物理存储上不连续连续随机访问效率O(N)O(1)插入、删除效率O(1)O(N) 3、链表的分类 链表根据结构分类,可分为单向/双向、无头结点/有头节点、非循环/循环链表,这三组每组各取…...
使用 Axios 获取用户数据并渲染——个人信息设置
目录 1. HTML 部分(前端页面结构) HTML 结构解析: 2. JavaScript 部分(信息渲染逻辑) JavaScript 解析: 3. 完整流程 4. 总结 5. 适用场景 本文将介绍如何通过 Axios 从服务器获取用户信息࿰…...
【hudi】基于hive2.1.1的编译hudi-1.0.0源码
hudi版本1.0.0 需要使用较低版本的hive,编译hudi只需要修改下类即可: org.apache.hudi.hadoop.hive.HoodieCombineHiveInputFormat 一、复制org.apache.hadoop.hive.common.StringInternUtils 找个hive2.3.9的源码包,创建包路径,…...
物联网领域的MQTT协议,优势和应用场景
MQTT(Message Queuing Telemetry Transport)作为轻量级发布/订阅协议,凭借其低带宽消耗、低功耗与高扩展性,已成为物联网通信的事实标准。其核心优势包括:基于TCP/IP的异步通信机制、支持QoS(服务质量&…...
MyBatis 调优指南:释放持久层性能潜力
MyBatis 作为一款优秀的持久层框架,以其灵活性和易用性深受开发者喜爱。然而,随着应用规模扩大和数据量增长,MyBatis 的性能问题也逐渐显现。本文将深入探讨 MyBatis 调优策略,帮助您释放持久层性能潜力。 一、 SQL 语句优化 避免…...
Unity扩展编辑器使用整理(一)
准备工作 在Unity工程中新建Editor文件夹存放编辑器脚本, Unity中其他的特殊文件夹可以参考官方文档链接,如下: Unity - 手册:保留文件夹名称参考 (unity3d.com) 一、菜单栏扩展 1.增加顶部菜单栏选项 使用MenuItemÿ…...
注册中心不知选哪个?Zookeeper、Eureka、Nacos、Consul和Etcd 5种全方位剖析对比
本文给大家讲解 5 种常用的注册中心,对比其流程和原理,无论是面试还是技术选型,都非常有帮助。 对于注册中心,在写这篇文章前,我其实只对 ETCD 有比较深入的了解,但是对于 Zookeeper 和其他的注册中心了解甚…...
Windows下怎么安装FFFmpeg呢?
在Windows下使用Open-webui报错,说Couldnt find ffmpeg or avconv,解决open-webui报错Couldn‘t find ffmpeg or avconv-CSDN博客于是尝试解决问题,那么Windows下怎么安装FFFmpeg呢? 尝试了两种方法。 第一种方法pip安装(失败&…...
CSS 基础:层叠、优先级与继承
CSS 基础:层叠、优先级与继承 一、层叠(Cascade)示例:层叠的顺序 二、优先级(Specificity)优先级规则示例:优先级的比较 三、继承(Inheritance)哪些属性会被继承…...
《翻转组件库之发布》
背景 继《翻转组件库之打包》_杨晓风-linda的博客-CSDN博客之后,组件库已经可以正常构建,那如何像elementUI等组件库那样,用npm安装,按照既定的用法使用即可呢?本篇便为你揭晓 资料相关 1、npm官方文档:…...
Spring Boot + Spring AI快速体验
Spring AI快速体验 1 什么是Spring AI 主要功能 2 快速开始 2.1 版本说明2.2 配置文件2.3 pom依赖 2.3.1 spring maven仓库2.3.2 核心依赖 2.4 定义ChatClient2.5 启动类2.6 测试 3 参考链接 1 什么是Spring AI Spring AI是Spring的一个子项目,是Spring专门面向于…...
windows linux常用基础命令
windows基础命令 cd …/ (访问D盘 直接D: 进入目录cd…\baidudu) color 2 改变颜色 dir 浏览当前目录中有什么内容 例如 dir windows可以浏览windows中有什么文件 cls 清屏 cd windows 可以跳转到c盘目录的下面 cd…/可以返回到上一级目录 ./当前目录 cd \ 直…...
ZooKeeper单节点详细部署流程
ZooKeeper单节点详细部署流程 文章目录 ZooKeeper单节点详细部署流程 一.下载稳定版本**ZooKeeper**二进制安装包二.安装并启动**ZooKeeper**1.安装**ZooKeeper**2.配置并启动**ZooKeeper** ZooKeeper 版本与 JDK 兼容性3.检查启动状态4.配置环境变量 三.可视化工具管理**Zooke…...
【AI日记】25.02.06
【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】【读书与思考】 AI kaggle 比赛:Backpack Prediction Challenge 读书 书名:理解公司:产权、激励与治理作者:张维迎下图感想:哲学家、思想家比如卢梭…...
税费学习之:附加税费
好的!我将从 **税收本质、历史沿革、用途逻辑、企业影响** 四个维度综合分析,用项目管理中的实际场景说明为什么需要缴纳附加税费。 --- ### **一、附加税费的本质与构成** #### **1. 定义** 附加税费是 **以增值税、消费税为基数征收的附加税**&…...
数据库开发常识(10.6)——SQL性能判断标准及索引误区(1)
10.6. 数据库开发常识 作为一名专业数据库开发人员,不但需要掌握数据库开发相关的语法和功能实现,还要掌握专业数据库开发的常识。这样,才能在保量完成工作任务的同时,也保质的完成工作任务,避免了为应用的日后维护埋下性能和稳定性方面的隐患。可遗憾的是,现实中,很大…...
网络原理一>数据链路层协议->以太网协议
目录 以太网协议的结构:类型:ARP请求应答报文:CRC:MTU: 为什么需要mac地址:mac地址和IP地址的区别: 以太网协议的结构: 以太网是数据链路层和物理层的主要协议 源IP,目的IP就不多说…...
Android 约束布局ConstraintLayout整体链式打包居中显示
Android 用约束布局ConstraintLayout实现将多个控件视作一个整体居中显示,使用 app:layout_constraintHorizontal_chainStyle"packed"实现 chain 除了链条方向有横向和竖向区分外, chain链条上的模式有 3种 spread - 元素将被展开&#…...
云计算行业分析
云计算作为数字经济的核心基础设施,未来十年将持续重塑全球科技格局,并渗透到几乎所有行业的数字化转型中。 一、云计算的发展潜力 1. 技术融合驱动爆发式创新 AI与云计算的深度耦合 - **智能云服务**:云厂商将提供预训练模型、自动化ML工…...
深入浅出DeepSeek LLM 以长远主义拓展开源语言模型
深入浅出地讲解DeepSeek LLM 以长远主义拓展开源语言模型 🌟 1. 什么是 DeepSeek LLM? 大家想象一下,你在游戏里要打造一个超级英雄角色,选择最强的装备、技能点和升级策略。那么,DeepSeek LLM 就是 AI 界的“超级英雄…...
用Python获取股票数据并实现未来收盘价的预测
获取数据 先用下面这段代码获取上证指数的历史数据,得到的csv文件数据,为后面训练模型用的 import akshare as ak import pandas as pd# 获取上证指数历史数据 df ak.stock_zh_index_daily(symbol"sh000001")# 将数据保存到本地CSV文件 df.…...
[openwrt]openwrt slaac only模式下部分终端无法获取到IPv6 DNS
问题描述 OpenWrt 中,如果启用了 RA 单播(ra_unicast),但部分终端无法获取到 DNS 信息 问题分析 RA 单播的局限性 并非所有终端都完全支持通过单播接收 RA 消息。部分终端可能无法正确解析单播 RA 中的 RDNSS(Recursive DNS Server)选项,从而导致无法获取 DNS 信息。终…...
【redis】数据类型之list
Redis的List数据类型是一个双向链表,支持在链表的头部(left)和尾部(right)进行元素的插入(push)和弹出(pop)操作。这使得List既可以用作栈(stack)…...
电脑连接wifi但是浏览器打开不了网页,使用手机热点能正常使用
电脑连接wifi但是浏览器打开不了网页,使用手机热点能正常使用 打开控制面板 打开网络和Internet(查看网络状态和任务) 点击更改适配器设置 双击WLAN 点击属性并双击打开Internet 协议版本4(TCP/IPv4) 将自动…...
el-table中的某个字段最多显示两行,超出部分显示“...详情”,怎么办
文章目录 背景需求需求分析 解决方案在线体验灵感来源我的实现方案 总结 背景 需求 比如,有如下一个表格,请你实现它: 要求: 最多显示两行超出部分显示为:“…详情”点击详情,展开全部内容 说明&#x…...
Vue el-input密码输入框 按住显示密码,松开显示*;阻止浏览器密码回填,自写密码输入框;校验输入非汉字内容;文本框聚焦到内容末尾;
输入框功能集合 <template><div style"padding: 10px"><!-- 密码输入框 --><el-input:type"inputType"v-model"password"placeholder"请输入密码"auto-complete"new-password"id"pwd"style…...
尚硅谷课程【笔记】——大数据之Shell【一】
课程视频:【【尚硅谷】Shell脚本从入门到实战】 一、Shell概述 为什么要学习Shell? 1)需要看懂运维人员的Shell程序 2)偶尔编写一些简单的Shell程序来管理集群、提高开发效率 什么是Shell? 1)Shell是一…...
4年测试|20-30K|金山办公|大模型测开3轮面经
一面时间:面试时长一小时左右 二面时间:面试时长基本满一小时 HR面时间:面试流程上全部结束了,内容如下: 前言: 岗位:自己想投递base珠海,金山办公的HR捞了下。why choose Zhuha…...
【负载均衡式在线OJ】实现负载均衡
目录 管理服务器 增加负载 && 减少负载 重置负载 && 获得负载 负载均衡 添加配置信息 什么是负载均衡 如何实现? 管理服务器 增加负载 && 减少负载 客户端访问一次服务器,负载就加1。客户端结束访问服务器,…...
网络安全-防御 第一次作业(由于防火墙只成功启动了一次未补截图)
防火墙安全策略课堂实验报告 一、拓扑 本实验拓扑包含预启动设备、DMZ区域(含OA Server和Web Server)、防火墙(FW1)、Trust区域(含办公区PC和生产区PC)等。具体IP地址及连接关系如给定拓扑图所示…...
大数据挖掘--两个角度理解相似度计算理论
文章目录 0 相似度计算可以转换成什么问题1 集合相似度的应用1.1 集合相似度1.1文档相似度1.2 协同过滤用户-用户协同过滤物品-物品协同过滤 1.2 文档的shingling--将文档表示成集合1.2.1 k-shingling1.2.2 基于停用词的 shingling 1.3 最小哈希签名1.4 局部敏感哈希算法&#…...
【Mybatis Plus】JSqlParser解析sql语句
【Mybatis Plus】JSqlParser解析sql语句 【一】JSqlParser 是什么【二】JSqlParser 的安装步骤【三】使用场景【1】sql语句解析【2】SQL 语句转换【3】SQL 语句生成【4】SQL 语句验证 【四】在使用 JSqlParser 时,如何处理 SQL 注入攻击?【1】使用预编译…...
vue3 + ElementPlus 封装列表表格组件包含分页
在前端开发中,封装组件是必不可少的。今天就来封装一个通用的列表表格组件,包含分页功能,可以提高代码的复用性和可维护性。 1. 组件设计 Props: tableData:表格数据。columns:表格列配置。totalÿ…...
springboot3整合knife4j详细版,包会!(不带swagger2玩)
1. 引入依赖 <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId><version>4.4.0</version> </dependency>2. 配置文件 简短必要版 # 配置springd…...
Vue2自定义指令实现优雅的前端埋点方案
背景介绍 在前端开发中,埋点是一个非常常见的需求。通常我们需要记录用户的操作行为,以便于后续的数据分析和问题排查。传统的埋点方式往往是在每个需要埋点的地方都写一段上报代码,这样不仅代码重复度高,而且维护起来也比较麻烦…...
1.攻防世界 题目名称-文件包含
进入题目页面如下 直接给出了源码进行代码审计 题目给出提示是文件包含的题 代码审计 <?php // 高亮显示当前 PHP 文件的源代码,方便查看和调试 highlight_file(__FILE__);// 包含名为 "check.php" 的文件,通常这个文件中可能包含一些用…...
Ruby Dir 类和方法详解
Ruby Dir 类和方法详解 引言 在Ruby编程语言中,Dir类是一个非常有用的工具,它允许我们与文件系统进行交互,如列出目录内容、检查文件是否存在等。Dir类提供了多种方法,使得文件系统的操作变得简单且高效。本文将详细介绍Ruby中的…...
axios 发起 post请求 json 需要传入数据格式
• 1. axios 发起 post请求 json 传入数据格式 • 2. axios get请求 1. axios 发起 post请求 json 传入数据格式 使用 axios 发起 POST 请求并以 JSON 格式传递数据是前端开发中常见的操作。 下面是一个简单的示例,展示如何使用 axios 向服务器发送包含 JSON 数…...
Windows编程:下载与安装 Visual Studio 2010
本节前言 在写作本节的时候,本来呢,我正在写的专栏,是 MFC 专栏。而 VS2010 和 VS2019,正是 MFC 学习与开发中,可以使用的两款软件。然而呢,如果你去学习 Windows API 知识的话,那么࿰…...
python学opencv|读取图像(五十七)使用cv2.bilateralFilter()函数实现图像像素双边滤波处理
【1】引言 前序学习过程中,已经掌握了对图像的基本滤波操作技巧,具体的图像滤波方式包括均值滤波、中值滤波和高斯滤波,相关文章链接有: python学opencv|读取图像(五十四)使用cv2.blur()函数实现图像像素…...
基于Typescript,使用Vite构建融合Vue.js的Babylon.js开发环境
一、创建Vite项目 使用Vite初始化一个VueTypeScript项目: npm create vitelatest my-babylon-app -- --template vue-ts cd my-babylon-app npm create vitelatest my-babylon-app -- --template vue-ts 命令用于快速创建一个基于 Vite 的 Vue TypeScript 项目。…...
DockerFile详细学习
目录 1.DockerFile介绍 2.DockerFile常用指令 3.指令详细讲解 4.实例 构建Node-Exporter 构建Alertmanager 构建Mariadb 1.DockerFile介绍 什么是 Dockerfile? Dockerfile 是一个文本文件,包含了构建 Docker 镜像的所有指令。 Dockerfile 是一…...
C++11详解(三) -- 可变参数模版和lambda
文章目录 1.可变模版参数1.1 基本语法及其原理1.2 包扩展1.3 empalce系列接口1.3.1 push_back和emplace_back1.3.2 emplace_back在list中的使用(模拟实现) 2. lambda2.1 lambda表达式语法2.2 lambda的捕捉列表2.3 lambda的原理 1.可变模版参数 1.1 基本…...
IDEA 中集成 Maven,配置环境、创建以及导入项目
目录 在 IntelliJ IDEA 中集成 Maven 并配置环境 1. 打开 IDEA 设置 2. 定位 Maven 配置选项 3. 配置 Maven 路径 4. 应用配置 创建 Maven 项目 1. 新建项目 2. 选择项目类型 3. 配置项目信息 4. 确认 Maven 设置 5. 完成项目创建 导入 Maven 项目 1. 打开导入窗口…...
讯飞智作 AI 配音技术浅析(三):自然语言处理
自然语言处理(NLP)是讯飞智作 AI 配音技术的重要组成部分,负责将输入的文本转换为机器可理解的格式,并提取出文本的语义和情感信息,以便生成自然、富有表现力的语音。 一、基本原理 讯飞智作 AI 配音的 NLP 技术主要包…...
html转PDF文件最完美的方案(wkhtmltopdf)
目录 需求 一、方案调研 二、wkhtmltopdf使用 如何使用 文档简要说明 三、后端服务 四、前端服务 往期回顾 需求 最近在做报表类的统计项目,其中有很多指标需要汇总,网页内容有大量的echart图表,做成一个网页去浏览,同时…...
漏洞挖掘 | 基于mssql数据库的sql注入
视频教程在我主页简介或专栏里 目录: 前记 0x1 判断网站数据库类型 0x2 了解mssql数据库的主要三大系统表 0x3 了解mssql的主要函数 0x4 判断注入点及其注入类型 0x5 联合查询之判断列数 0x6 联合查询之获取数据库相关信息 0x7 mssql之时间盲注 0x8 mssql之报错注…...
.Net Core笔记知识点(跨域、缓存)
设置前端跨域配置示例: builder.Services.AddCors(option > {option.AddDefaultPolicy(policy > {policy.WithOrigins(originUrls).AllowAnyMethod().AllowAnyHeader().AllowCredentials();});});var app builder.Build();app.UseCors(); 【客户端缓存】接…...
JS实现一个通用的循环填充数组的方法
function createFilledArray(length, pattern) {return Array.from({ length }, (_, i) > pattern[i % pattern.length]); }// 示例 const result createFilledArray(8, [1, 2, 3]);console.log(result); // [1, 2, 3, 1, 2, 3, 1, 2]解析: createFilledArray(…...
Java项目: 基于SpringBoot+mybatis+maven+mysql实现的智能学习平台管理系(含源码+数据库+毕业论文)
一、项目简介 本项目是一套基于SpringBootmybatismavenmysql实现的智能学习平台管理系统 包含:项目源码、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过严格调试,eclipse或者idea 确保可以运行! 该系统功能完善、…...