javaEE初阶————多线程初阶(2)
今天给大家带来第二期啦,保证给大家讲懂嗷;
1,线程状态
NEW | 安排了工作还未开始行动 |
RUNNABLE | 可工作的,或者即将工作,正在工作 |
BLOCKED | 排队等待 |
WAITING | 排队等待其他事 |
TIMED_WAITING | 排队等待其他事 |
TERMINATED | 工作完成了 |
1.1 观察线程的所有状态
1) new
new就是创建了Thread对象还没有开始使用,也就是没有start
public class Demo1 {public static void main(String[] args) {Thread t1 = new Thread(()->{System.out.println(1111); });System.out.println(t1.getState());}
}
看运行结果;
2) RUNNABLE
可工作的,又被分为即将开始工作和正在工作,这个就是在操作系统层面进程的就绪状态,用代码说明吧,简单明了;
Thread t2 = new Thread(()->{while(true){System.out.println(11111);}});t2.start();
运行结果一定是疯了一样的打印11111,我们借助jconsole来看线程状态;
正在运行RUNNABLE;
3)TERMINATED
工作完成了,虽然内核中的线程已经结束了,但是Thread对象还在;
4) WAITING
死等,还是上代码,
public class Demo1 {public static void main(String[] args) throws InterruptedException {Thread t2 = new Thread(()->{while(true){System.out.println(11111);}});t2.start();t2.join();System.out.println(22222);}
}
我们让主线程main来等着t2看看的状态;
运行结果还是无线的,看不到22222;
mian的状态是WAITING,正在死等谈线程结束,这里面我们没有命名,系统自动给t2起名字了,t2还是RUNNABLE状态;BLOCKED状态我们之后说,我们还没有讲锁;
5) TIMED_WAITING
不是死等了,有时间限制的等待,(你还在等你的女神吗,她只会影响你变强的速度!!);
public class Demo2 {public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(()->{while (!Thread.interrupted()){System.out.println("等一等~");try {Thread.sleep(1000);} catch (InterruptedException e) {break;}}});t1.start();t1.join(10000);t1.interrupt();System.out.println(Thread.currentThread().getName() + "劳资不等了!");}
}
看这个代码,我们让mian线程等待t1线程10秒,但是t1线程是没有停下来的意思的,运行结果
我们在运行一次,趁着这10秒来看看main线程的状态,
TIMED_WAITING 有时间的等待;
sleep也是会陷入有时间的等待的;我们刚才是站在线程之间的角度,而他t1线程中
t1线程在sleep之前是RUNNABLE, 在sleep时候是TIMED_WAITNG,之后还是RUNNABLE;
我们来试试;
public class Demo3 {public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(()->{while (!Thread.interrupted()){System.out.println("等一等~");try {System.out.println(Thread.currentThread().getState());Thread.sleep(5000);System.out.println(Thread.currentThread().getState());} catch (InterruptedException e) {break;}}});t1.start();}
}
sleep前后都是RUNNABLE状态,而休眠的时候是TIMED_WAITING状态;
1.2 线程状态和状态转移的意义
多线程编程中,为啥要引入这些状态呢,我们在1多线程程序中了解多线程状态是我们调试代码成功的关键,这也是我们学习多线程最基础的部分;
———————————————————————————————————————————
2,多线程带来的风险——(线程安全)
2.1 线程安全的概念
什么是线程安全?就我们单线程代码在多线程程序中能够按照预期正常运行我们就说该多线程程序是线程安全的;
2.2 观察线程不安全
我们来写一个多线程代码,让两个线程对同一操作数进行修改;
public class Demo1 {public static int count = 0;public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(()->{for (int i = 0; i < 5000; i++) {count++;}});Thread t2 = new Thread(()->{for (int i = 0; i < 5000; i++) {count++;}});t1.start();t2.start();t1.join();t2.join();System.out.println(count);}
}
代码中我们让两个线程对成员变量count进行修改, 启动两个线程,并且让主线程等待两个线程,我们来看运行结果;
8千多,吞我1000多的数字,怎么个事,这个有两个原因,一个是原子性,另一个是罪魁祸首,就是线程调度的随机性,这两个线程是并发执行的;我们一会儿来详细讲一下这两种情况的解决办法;
2.3 线程不安全的原因
先来讨论下join;
join:
我们在代码中使用了join,同学们想过为啥要使用join没有,既然我们说过线程调度是随机的,那么有没有可能打印的count是0呢,屏蔽join后运行
是0吧,这就是因为操作系统的随机调度,线程1,2还在给count++,而我们的main线程只有打印,自然就程序开始就打印,不等那两个线程啦,我们加上join就让main等等那两个线程,这时又有同学问了,你刚才打印的8000多的数字,是不是因为count还没++完呢,你main线程就先打印了呢? 这一点事不可能1的,我们再来讲解一下
这也对,那也对,结果就是不对,为啥啊,线程并发执行并且随机调度!奶奶的我刚才了解了,那就因为这个给我++操作吃了?它咋吃的啊?
这就要我们站在CPU的角度来看了,
就这一小段指令在CPU上是三段指令
1,读取 load 把内存中的值读到CPU上的寄存器中
2,修改 add 将寄存器中的值++
3,存储 save 将寄存器中的值放回内存中
我们所说的线程的随机调度是可能发生在这几步CPU操作当中的,可能我们线程二一顿++,到线程一又变成一了;这个我们马上详解来画;
我们先来聊聊原子可见性:
原子性:
我们不讲概念,我们就想想购票,如果你正在买最后一张票,你购买成功,在没有及时更新数据库的时候另一个人也看到了这张票,把它买下,那么一张票卖给了两个人,这不就是错误吗,我们想想为什么会出现这个原因,因为购票的操作不是原子的,购票操作有查票,买票,把数据更新到数据库中,我们在最后更新数据库的时候让其他线程插队了,这不就是刚才两个线程给count++的情况吗,我们要做的是把狗票操作锁到一块,让其他线程不能插队!
原子不可再分,这便是原子性;
可见性:一个线程对共享变量的修改,在其他线程能够看到
JMM————java内存模型
java虚拟机规范中定义了java内存模型————原因就是我们的特点——一次运行到处编译
为了屏蔽操作系统和各种硬件的内存访问差异;
每个线程独有的 “工作内存” (WorkingMemory)————可以理解为寄存器
线程之间的共享变量:“主内存” (MainMemory)————可以理解为内存
总之呢,导致内存不安全的原因呢:
1,根本) 线程之间随机调度,抢占式执行
2,多个线程同时修改一个变量
3,修改操作不是原子的
4,内存可见性
5,指令重排序(这个我们后面说)
———————————————————————————————————————————
2.4 解决之前的线程不安全问题
两个方法,
1,
public class Demo2 {public static int count = 0;public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(()->{for (int i = 0; i < 5000; i++) {count++;}});Thread t2 = new Thread(()->{for (int i = 0; i < 5000; i++) {count++;}});t1.start();t1.join();t2.start();t2.join();System.out.println(count);}
}
直接修改程序执行的顺序,直接不启动t2线程,先让t1线程执行完,在去执行t2,但是并发很慢,我们想让他俩一起执行呀;
第二种方法:锁
public class Demo3 {public static int count = 0;public static void main(String[] args) throws InterruptedException {Object locker1 = new Object();Thread t1 = new Thread(()->{for (int i = 0; i < 5000; i++) {synchronized(locker1){count++;}}});Thread t2 = new Thread(()->{for (int i = 0; i < 5000; i++) {synchronized (locker1){count++;}}});t1.start();t2.start();t1.join();t2.join();System.out.println(count);}
}
我们接下来就好好讲讲锁;
———————————————————————————————————————————
3,synchronized 关键字
3.1 synchronized的特性
1)互斥
两个线程要同时使用一个锁对象时会发生阻塞等待:
Object locker = new Object();synchronized(locker){System.out.println(11);}
互斥是发生在两个synchronized语句使用同一个锁对象的时候,锁对象就是locker,我们可以定义为任何类型,这个对象也可以有自己的用途,代码块中的System.out.println就是我们加锁的语句,进代码块加锁,出代码块解锁;我们解释下刚才那段代码Deom3那个;
public class Demo2 {public static int count = 0;public static void main(String[] args) throws InterruptedException {Object locker1 = new Object();Thread t1 = new Thread(()->{for (int i = 0; i < 5000; i++) {synchronized(locker1){count++;}}});Thread t2 = new Thread(()->{for (int i = 0; i < 5000; i++) {synchronized (locker1){count++;}}});t1.start();t2.start();t1.join();t2.join();System.out.println(count);}
}
我们这里是对count++这一操作加锁,让他在CPU上的三步指令操作可以当做一个了,我们必须执行完三步指令才能让其他线程执行,否则一直阻塞等待;
2)可重入
同一个线程多次对使用一个锁不会发生阻塞等待;
public class Demo3 {static int count = 0;public static void main(String[] args) throws InterruptedException {Object locker = new Object();Thread t1 = new Thread(()->{synchronized (locker){synchronized (locker){count++;}}});t1.start();t1.join();System.out.println(count);}
}
我们看这段代码,我们在t1线程使用了两个锁,都去竞争locker,
我们实际来运行一下,
“你刚才Dog叫什么呢,这不没问题吗”,“冤枉啊”,这是因为java中的锁是可重入锁,内部使用计数器来实现;可重入锁呢,他是在让锁对象内部保存了是哪个线程持有了这把锁,后序在对当前锁对象加锁的时候检查一下是那个线程,
3.2 synchronized 使用式例
1)修饰代码块,指定锁对象
public class Demo4 {public static void main(String[] args) {Object locker = new Object();Thread t1 = new Thread(()->{synchronized (Thread.currentThread()){System.out.println(1111);}});Thread t2 = new Thread(()->{synchronized (locker){System.out.println(2222);}});t1.start();t2.start();}
}
我们可以使用任意锁对象或者线程对象本身;
2)synchronized修饰普通方法
Object locker = new Object();public synchronized int add(int a,int b){return a+b;}//等价于public int add2(int a,int b){synchronized (locker){return a+b;}}
3)synchronized修饰静态方法
public synchronized static int add3(int a,int b){return a+b;}
不一一介绍了;
3.3 Java标准库中的线程安全类
我们之前学的数据结构,在多线程中基本都是线程不安全的,
这里给大家列举一些安全的,但先不一一展开讲了;
1,vector
2,HashTable
3,ConcurrentHashMap(强推)
4,StringBuffer
下期再见嗷;
相关文章:
javaEE初阶————多线程初阶(2)
今天给大家带来第二期啦,保证给大家讲懂嗷; 1,线程状态 NEW安排了工作还未开始行动RUNNABLE可工作的,或者即将工作,正在工作BLOCKED排队等待WAITING排队等待其他事TIMED_WAITING排队等待其他事TERMINATED工作完成了 …...
linux下的NFS和FTP部署
目录 NFS应用场景架构通信原理部署权限认证Kerberos5其他认证方式 命令serverclient查看测试系统重启后自动挂载 NFS 共享 高可用实现 FTP对比一些ftp服务器1. **vsftpd (Very Secure FTP Daemon)**2. **ProFTPD (Professional FTP Daemon)**3. **Pure-FTPd**4. **WU-FTPD (Was…...
《Java核心技术II》可中断套接字
4.2.4 可中断套接字 SocketChannel可以中断套接字 SocketChannel channel.open(new InetSocketAddress(host,port)); 通道(channel)并没有与之相关联的流,实际上,所拥有的read和write方法都是通过Buffer对象实现的。 如果不想处理缓冲区,…...
电梯系统的UML文档05
Dispatcher 不控制实际的电梯组件,但它在软件系统中是重要的。每一个电梯有一个ispatcher,主要功能是计算电梯的移动方向、移动目的地以及保持门的打开时间。它和系统中除灯控制器以外的几乎所有控制对象交互。 安全装置也是一个环境对象,它…...
浅谈云计算19 | OpenStack管理模块 (上)
OpenStack管理模块(上) 一、操作界面管理架构二、认证管理2.1 定义与作用2.2 认证原理与流程2.2.1 认证机制原理2.2.2 用户认证流程 三、镜像管理3.1 定义与功能3.2 镜像服务架构3.3 工作原理与流程3.3.1 镜像存储原理3.3.2 镜像检索流程 四、计算管理4.…...
1.5 GPT 模型家族全解析:从 GPT-1 到 GPT-4 的演进与创新
GPT 模型家族全解析:从 GPT-1 到 GPT-4 的演进与创新 随着人工智能技术的飞速发展,GPT(Generative Pre-trained Transformer)模型家族已经成为了现代自然语言处理(NLP)领域的标杆。从初代的 GPT-1 到最新的 GPT-4,每一代模型的发布都标志着人工智能技术的一个飞跃,并推…...
C#如何调用执行命令行窗口(CMD)
一、引言 在 C# 的编程世界里,我们常常会遇到需要与操作系统底层进行交互的场景。这时,调用命令行窗口(CMD)就成为了一个强大的工具。无论是自动化日常任务,还是执行外部程序和批处理文件,通过 C# 调用 CM…...
归子莫的科技周刊#2:白天搬砖,夜里读诗
归子莫的科技周刊#2:白天搬砖,夜里读诗 本周刊开源,欢迎投稿。 刊期:2025.1.5 - 2025.1.11。原文地址。 封面图 下班在深圳看到的夕阳,能遇到是一种偶然的机会,能拍下更是一种幸运。 白天搬砖,…...
Spring Boot + Apache POI 实现 Excel 导出:BOM物料清单生成器(支持中文文件名、样式美化、数据合并)
目录 引言 Apache POI操作Excel的实用技巧 1.合并单元格操作 2.设置单元格样式 1. 创建样式对象 2. 设置边框 3. 设置底色 4. 设置对齐方式 5. 设置字体样式 6.设置自动换行 7. 应用样式到单元格 3. 定位和操作指定单元格 4.实现标签-值的形式 5.列宽设置 1. 设…...
OpenVela——专为AIoT领域打造的开源操作系统
目录 一、系统背景与开源 1.1. 起源 1.2. 开源 二、系统特点 2.1. 轻量化 2.2. 标准兼容性 2.3. 安全性 2.4. 高度可扩展性 三、技术支持与功能 3.1. 架构支持 3.2. 异构计算支持 3.3. 全面的连接套件 3.4. 开发者工具 四、应用场景与优势 4.1. 应用场景 4.2. …...
02UML图(D1_结构图)
目录 学习前言 ---------------------------------- 讲解一:类图 一、类图的组成结构 1. 类(Class) 1.1. 类的成员变量的表示方式 1.2. 类的成员方法的表示方式 2. 接口(Interface) 3. 包(Package) 二、UML类…...
二十三种设计模式-装饰器模式
一、定义与核心思想 装饰器模式是一种结构型设计模式,其核心思想是动态地给一个对象添加一些额外的职责。通过这种方式,可以在不改变原有对象结构的基础上,灵活地增加新的功能,使得对象的行为可以得到扩展,同时又保持…...
SSM课设-酒店管理系统功能设计
【课设者】SSM课设-酒店管理系统 分为用户端管理员端 技术栈: 后端: Spring Spring MVC MyBatis Mysql JSP 前端: HtmlCssJavaScriptAjax 功能: 用户端主要功能包括: 登录注册 客房预订 客房评论 首页 管理员端主要功能包括: 会员信息管理 客房信息…...
R语言的文件操作
R语言的文件操作 引言 在数据科学和分析的过程中,文件操作是不可或缺的一部分。R语言作为一种强大的统计计算和图形作图的编程语言,提供了丰富的文件操作函数,使得用户能够方便地读取和保存数据。本文将详细介绍R语言中的文件操作ÿ…...
[javaWeb]初识Web
将该图片在浏览器中打印出来 代码: <html> <head> <title>HTML初识</title> </head> <body> <h1>猫猫</h1> <img src "img/1.jpg"> </body> &l…...
基于微信小程序的摄影竞赛系统设计与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
.netframwork模拟启动webapi服务并编写对应api接口
在.NET Framework环境中模拟启动Web服务,可以使用几种不同的方法。一个常见的选择是利用HttpListener类来创建一个简单的HTTP服务器,或者使用Owin/Katana库来自托管ASP.NET Web API或MVC应用。下面简要介绍Owin/Katana示例代码。这种方法更加灵活&#x…...
Go语言之路————条件控制:if、for、switch
Go语言之路————if、for、switch 前言ifforswitchgoto和label 前言 我是一名多年Java开发人员,因为工作需要现在要学习go语言,Go语言之路是一个系列,记录着我从0开始接触Go,到后面能正常完成工作上的业务开发的过程࿰…...
54,【4】BUUCTF WEB GYCTF2020Ezsqli
进入靶场 吓我一跳,但凡放个彭于晏我都不说啥了 提交个1看看 1 and 11 1# 还尝试了很多,不过都被过滤了,头疼 看看别人的WP 竟然要写代码去跑!!!,不会啊,先用别人的代码吧…...
在线图片压缩工具
在线图片压缩工具,无需登录,无需成本,用完就走。 包括中文和英文版本。 官网地址: https://compress.openai2025.com/ 效果:...
快手极速版如何查找ip归属地?怎么关掉
在数字化时代,个人隐私的保护成为了广大用户关注的焦点。快手极速版作为一款备受欢迎的短视频应用,其IP归属地的显示与关闭功能自然也成了用户热议的话题。本文将详细介绍如何在快手极速版中查找IP归属地以及如何关闭IP属地显示,帮助用户更好…...
精准掌握:Nginx匹配规则及其优先级解析
Nginx作为一款高性能的HTTP和反向代理服务器,其配置文件的匹配规则及优先级设置对于实现精确的请求路由和资源分配至关重要。本文将深入探讨Nginx的匹配规则及其优先级,帮助读者更好地理解和应用这些配置。 一、Nginx匹配规则概述 Nginx的匹配规则主要…...
在VS2022中用C++连接MySQL数据库读取数据库乱码问题
1.正确安装mysql 安装之后的配置文件 2.在VS2022中进行相关配置 (1)右键项目,打开属性 注意是右键项目,不是.cpp文件 (2)配置属性-> VC目录 -> 包含目录 ->添加头文件路径(如图&am…...
RocketMQ源码分析之事务消息分析
rocketMQ事务消息原理概述 RocketMQ采用两阶段提交(2PC)的思想来实现事务消息,当事务消息失败或者超时,同时采用补偿的方式处理这个问题。这两个阶段分别为正常事务消息的发送与提交以及事务消息的补偿。我们看看官方文档给的事务…...
2025.1.19机器学习笔记:PINN文献精读
第三十周周报 一、文献阅读题目信息摘要Abstract创新点物理背景网络框架实验实验一:直道稳定流条件实验二:环状网络中的非稳定流条件 结论缺点及展望 二、代码实践总结 一、文献阅读 题目信息 题目:《Enhanced physics-informed neural net…...
大文件上传服务-后端V1V2
文章目录 大文件上传概述:minio分布式文件存储使用的一些技术校验MD5的逻辑 uploadV1 版本 1uploadv2 版本 2 大文件上传概述: 之前项目做了一个文件上传的功能,最近看到有面试会具体的问这个上传功能的细节,把之前做的项目拿过来总结一下,自己写的一个…...
docker 基础语法学习,K8s基础语法学习,零基础学习
下面是关于Docker和Kubernetes的基础语法学习资料,包括一些关键概念和示例代码。 Docker 基础语法 1. 安装 Docker 首先,你需要安装 Docker。以下是不同操作系统上的安装指南: Windows/Mac: 下载并安装 Docker Desktop。 Linux: 根据你的…...
【网络协议】RFC3164-The BSD syslog Protocol
引言 Syslog常被称为系统日志或系统记录,是一种标准化的协议,用于网络设备、服务器和应用程序向中央Syslog服务器发送日志消息。互联网工程任务组(IETF)发布的RFC 3164,专门定义了BSD Syslog协议的规范和实现方式。通…...
MongoDB深度解析与实践案例
MongoDB深度解析与实践案例 在当今大数据与云计算盛行的时代,NoSQL数据库以其灵活的数据模型、水平扩展能力和高性能,成为处理海量数据的重要工具之一。MongoDB,作为NoSQL数据库的杰出代表,凭借其面向文档的存储结构、强大的查询语言以及丰富的生态系统,赢得了众多开发者…...
C语言从零到精通:常用运算符完全指南,掌握算术、逻辑与关系运算
系列文章目录 01-C语言从零到精通:常用运算符完全指南,掌握算术、逻辑与关系运算 文章目录 系列文章目录前言一、C语言的起源与应用领域1.1 C语言的起源1.2 C语言的应用领域1.2.1 操作系统开发1.2.2 嵌入式系统1.2.3 编译器开发1.2.4 游戏开发与图形处理…...
ArkUI概述
鸿蒙操作系统(HarmonyOS)是华为公司推出的一款面向未来、面向全场景的分布式操作系统。它不仅能够支持各种不同的设备,从手机、平板到智能穿戴和智能家居产品,而且为开发者提供了一套统一的开发环境和工具链。对于想要深入鸿蒙开发…...
浅谈计算机网络03 | 现代网络组成
现代网络组成 一 、网络生态体系1.1网络生态系统的多元主体1.2 网络接入设施的多样类型 二、现代网络的典型体系结构解析三、高速网络技术3.1 以太网技术3.2 Wi-Fi技术的深度剖析3.2.1 应用场景的多元覆盖3.2.2 标准升级与性能提升 3.3 4G/5G蜂窝网的技术演进3.3.1 蜂窝技术的代…...
在线图片马赛克处理工具
在线图片马赛克处理工具,无需登录,无需费用,用完就走。 包括中文和英文版本 官网地址: https://mosaic.openai2025.com...
文件上传 分片上传
分片上传则是将一个大文件分割成多个小块分别上传,最后再由服务器合并成完整的文件。这种做法的好处是可以并行处理多个小文件,提高上传效率;同时,如果某一部分上传失败,只需要重传这一部分,不影响其他部分…...
网络安全---CMS指纹信息实战
CMS简介 CMS(Content Management System)指的是内容管理系统,如WordPress、Joomla等。CMS系统非常常见,几乎所有大型网站都使用CMS来管理其网站的内容。由于常见CMS的漏洞较多,因此黑客将不断尝试利用这些漏洞攻击CMS…...
Ubuntu 24.04 LTS 系统语言英文改中文
Ubuntu 24.04 LTS 修改软件源 Ubuntu 更改软件源 修改语言 无需输入命令,为Ubuntu 24.04系统添加中文智能拼音输入法 在 setting 的 system 中按下图操作 点击“Apply Changes”。需要管理员密码,安装完成后,退出登录,重新登…...
信创在医疗领域的应用:开启医疗信息化新时代
信创在医疗领域的应用:开启医疗信息化新时代 信创在医疗领域的应用:开启医疗信息化新时代信创医疗自助一体机杭医基于信创底座的健康医疗大数据平台厦门大学附属成功医院基于海光CPU的信创改造中科可控基于海光CPU的智慧医疗解决方案 信创在医疗领域的应…...
力扣-数组-303 区域和检索-数组不可变
解析 题目有点费解,大致应该是给出区间内的和,然后维护一个前缀和,为了防止越界,先填一个0进去,在构建的时候也要注意此时构建的dp的下标是i1,所以加的前缀和的下标是i。 代码 class NumArray { public:…...
【CSS】---- CSS 实现超过固定高度后出现展开折叠按钮
1. 实现效果 2. 实现方法 使用 JS 获取盒子的高度,来添加对应的按钮和样式;使用 CSS 的浮动效果,参考CSS 实现超过固定高度后出现展开折叠按钮;使用容器查询 – container 语法;使用 clamp 函数进行样式判断。 3. 优…...
二十项零信任相关的前沿和趋势性技术-MASQUE
影响力评级:较低 市场渗透率:不到目标受众的 1% 成熟度:孵化 定义:基于QUIC加密的多路复用应用程序底层 (MASQUE) 是一个 IETF 标准草案,可实现流量的安全传输和代理。 MASQUE全称为:Multiplexed Appli…...
【Docker】使用Dev Container进行开发
工作区 Dev Container 设置 新建一个文件夹 ./devcontainer 然后下面放 devcontainer.json 然后安装 vscode dev container 插件,然后 CtrlShiftP 启动 Container {"name": "PyTorch-Julia Development","image": "x66ccff/p…...
搭建一个基于Spring Boot的数码分享网站
搭建一个基于Spring Boot的数码分享网站可以涵盖多个功能模块,例如用户管理、数码产品分享、评论、点赞、收藏、搜索等。以下是一个简化的步骤指南,帮助你快速搭建一个基础的数码分享平台。 — 1. 项目初始化 使用 Spring Initializr 生成一个Spring …...
在线json格式化工具
在线json格式化工具,包括中文和英文版本,无需登录,无需费用,用完就走。 官网地址: https://json.openai2025.com 效果如下:...
leetcode300.最长递增子序列
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。 示例 1&…...
【个人学习记录】软件开发生命周期(SDLC)是什么?
软件开发生命周期(Software Development Life Cycle,SDLC)是一个用于规划、创建、测试和部署信息系统的结构化过程。它包含以下主要阶段: 需求分析(Requirements Analysis) 收集并分析用户需求定义系统目标…...
CTE与临时表:优劣势对比及使用场景分析
在数据库开发中,尤其是在复杂查询和优化中,**公共表表达式(CTE)和临时表(Temporary Table)**是两种常用的工具。尽管它们的功能有些相似,都是为了处理中间结果集,但它们的优劣势和使…...
Kali环境变量技巧(The Environment Variable Technique Used by Kali
Kali环境变量技巧 朋友们好,我们今天继续更新《黑客视角下的Kali Linux的基础与网络管理》中的管理用户环境变量。为了充分利用我们的黑客操作系统Kali Linux,我们需要理解和善于使用环境变量,这样会使我们的工具更具便利,甚至具…...
Ubuntu 24.04 LTS linux 文件权限
Ubuntu 24.04 LTS 文件权限 读权限 :允许查看文件的内容。写权限 (w):允许修改文件的内容。执行权限 (x):允许执行文件(对于目录来说,是进入目录的权限)。 文件权限通常与三类用户相关联: 文…...
多个版本JAVA切换(学习笔记)
多个版本JAVA切换 很多时候,我们电脑上会安装多个版本的java版本,java8,java11,java17等等,这时候如果想要切换java的版本,可以按照以下方式进行 1.检查当前版本的JAVA 同时按下 win r 可以调出运行工具…...
AI刷题-最小替换子串长度、Bytedance Tree 问题
目录 一、最小替换子串长度 问题描述 输入格式 输出格式 输入样例 1 输出样例 1 输入样例 2 输出样例 2 解题思路: 问题理解 数据结构选择 算法步骤 最终代码: 运行结果: 二、Bytedance Tree 问题 问题描述 输入格式 输…...