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

并发编程系列(一) -多线程技术快速入门

最近对 Java 并发编程技术知识进行了重新整理,再次献上文章合集索引,感兴趣的小伙伴可以直接点击如下地址快速阅读。

  • 并发编程系列(一) -多线程技术快速入门
  • 并发编程系列(二) -Thread类介绍
  • 并发编程系列(三) -synchronized关键字介绍
  • 并发编程系列(四) -volatile关键字介绍
  • 并发编程系列(五) -死锁产生原因介绍
  • 并发编程系列(六) -线程等待与唤醒机制介绍
  • 并发编程系列(七) -本地线程ThreadLocal类介绍
  • 并发编程系列(八) -可重入锁ReentrantLock类介绍(上)
  • 并发编程系列(九) -可重入锁ReentrantLock类介绍(下)
  • 并发编程系列(十) -读写锁ReadWriteLock类介绍
  • 并发编程系列(十一) -超高并发读写锁StampedLock类介绍
  • 并发编程系列(十二) -生产者和消费者模型介绍
  • 并发编程系列(十三) -阻塞队列BlockingQueue介绍
  • 并发编程系列(十四) -线程组介绍
  • 并发编程系列(十五) -线程池技术介绍
  • 并发编程系列(十六) -常用线程并发同步技术介绍
  • 并发编程系列(十七) -常用并发原子操作技术介绍
  • 并发编程系列(十八) -AQS设计原理解读

一、简介

在很多场景下,我们经常听到采用多线程编程,能显著的提升程序的执行效率。例如执行大批量数据的插入操作,采用单线程编程进行插入可能需要 30 分钟,采用多线程编程进行插入可能只需要 5 分钟就够了。

既然多线程编程技术如此厉害,那什么是多线程呢?

在介绍多线程之前,我们还得先讲讲进程和线程的概念。

二、进程和线程

2.1、什么是进程?

从计算机角度来讲,进程是操作系统中的基本执行单元,也是操作系统进行资源分配和调度的基本单位,并且进程之间相互独立,互不干扰

例如,我们windows电脑中的 Chrome 浏览器是一个进程、WeChat 也是一个进程,正在操作系统中运行的.exe都可以理解为一个进程。

2.2、什么是线程?

关于线程,比较官方的定义是,线程是进程中的⼀个执⾏单元,也是操作系统能够进行运算调度的最小单位,负责当前进程中程序的执⾏。同时⼀个进程中⾄少有⼀个线程,⼀个进程中也可以有多个线程,它们共享这个进程的资源,拥有多个线程的程序,我们也称为多线程编程。

举个例子,Chrome 浏览器和 WeChat 是两个进程,Chrome 浏览器进程里面有很多线程,例如 HTTP 请求线程、事件响应线程、渲染线程等等,线程的并发执行使得在浏览器中点击一个新链接从而发起 HTTP 请求时,浏览器还可以响应用户的其它事件。

2.3、进程和线程的关系

关于进程和线程,可能上面的解释过于抽象,还是很难理解,下面是一段出自阮一峰老师博客文章的介绍,可能描述不是非常严谨,但是足够形象,有助于我们对它们关系的理解。

  • 1.我们都知道,计算机的核心是 CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运行;(CPU 类似于工厂
  • 2.假定工厂的电力有限,一次只能供给一个车间使用。也就是说,一个车间开工的时候,其他车间都必须停工。背后的含义就是,单个 CPU 一次只能运行一个任务;
  • 3.进程就好比工厂的车间,它代表 CPU 所能处理的单个任务。任一时刻,CPU 总是运行一个进程,其他进程处于非运行状态;(进程类似于车间
  • 4.一个车间里,可以有很多工人。他们协同完成一个任务;
  • 5.线程就好比车间里的工人。一个进程可以包括多个线程;(线程类似于工人
  • 6.车间的空间是工人们共享的,比如许多房间是每个工人都可以进出的。这象征一个进程的内存空间是共享的,每个线程都可以使用这些共享内存;(每个线程共享进程下的内存资源
  • 7.一个防止他人进入的简单方法,就是门口加一把锁。先到的人锁上门,后到的人看到上锁,就在门口排队,等锁打开再进去。这就叫"互斥锁"(Mutual exclusion,缩写 Mutex),防止多个线程同时读写某一块内存区域;(多个线程下可以通过互斥锁,实现资源独占
  • 8.还有些房间,可以同时容纳 n 个人,比如厨房。也就是说,如果人数大于 n,多出来的人只能在外面等着。这好比某些内存区域,只能供给固定数目的线程使用;
  • 9.这时的解决方法,就是在门口挂 n 把钥匙。进去的人就取一把钥匙,出来时再把钥匙挂回原处。后到的人发现钥匙架空了,就知道必须在门口排队等着了。这种做法叫做 “信号量”(Semaphore),用来保证多个线程不会互相冲突。(多个线程下可以通过信号量,实现互不冲突

不难看出,互斥锁 Mutex 是信号量 semaphore 的一种特殊情况(n = 1时)。也就是说,完全可以用后者替代前者。但是,因为 Mutex 较为简单,且效率高,所以在必须保证资源独占的情况下,还是采用这种方式。

2.4、为什么要引入线程?

早期的操作系统都是以进程作为独立运行的基本单位的,直到后期计算机科学家们又提出了更小的能独立运行的基本单位,也就是线程。

那为什么要引入线程呢?我们只需要记住这句话:线程又称为迷你进程,但是它比进程更容易创建,也更容易撤销

引入线程之后,可以将复杂的操作进一步分解,让程序的执行效率进一步提升

举个例子,进程就如同一个随时背着粮草和机枪的士兵,这样肯定会造成士兵的执行战斗的速度。因此,一个简单想法就是:分配两个人来执行,一个士兵负责随时背着粮草,另一个士兵负责抗机枪战斗,这样执行战斗的速度会大幅提升。这些轻装上阵的士兵,可以理解为我们上文提到的线程!

从计算机角度来说,由于创建或撤销进程时,系统都要为之分配或回收资源,如内存空间、I/O 设备等,需要较大的时间和空间开销。

为了减少进程切换的开销,把进程作为资源分配单位和调度单位这两个属性分开处理,即进程还是作为资源分配的基本单位,但是把调度执行与切换的责任交给线程,即线程成为独立调度的基本单位,它比进程更容易(更快)创建,也更容易撤销。

一句话总结就是:引入线程前,进程是资源分配和独立调度的基本单位。引入线程后,进程是资源分配的基本单位,线程是独立调度的基本单位,线程也是进程中的⼀个执⾏单元。

三、创建线程的方式

在 Java 里面,创建线程有以下两种方式:

  • 继承java.lang.Thread类,重写run()方法
  • 实现java.lang.Runnable接口,然后通过一个java.lang.Thread类来启动

不管是哪种方式,所有的线程对象都必须是Thread类或其⼦类的实例,每个线程的作⽤是完成⼀定的任务,实际上就是执⾏⼀段程序流,即⼀段顺序执⾏的代码,任务执行完毕之后就结束了。

在 Java 中,通过Thread类来创建并启动线程的步骤如下:

  • 1.定义Thread类的⼦类,并重写该类的run()方法
  • 2.通过Thread子类,初始化线程对象
  • 3.通过线程对象,调用start()方法启动线程

下面我们具体来看看创建线程的代码实践。

3.1、继承 Thread 类,重写 run 方法介绍
/*** 创建一个 Thread 子类*/
public class Thread0 extends Thread {@Overridepublic void run() {for (int i = 0; i < 5; i++) {String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(new Date());System.out.println(time + " 当前线程:" + Thread.currentThread().getName() + ",正在运行");}}
}
/*** 创建一个测试类*/
public class ThreadTest0 {public static void main(String[] args) {// 初始化一个线程对象,然后启动线程Thread0 thread0 = new Thread0();thread0.start();for (int i = 0; i < 5; i++) {String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(new Date());System.out.println(time + " 当前线程:" + Thread.currentThread().getName() + ",正在运行");}}
}

输出结果:

2023-08-23 17:58:03:726 当前线程:Thread-0,正在运行
2023-08-23 17:58:03:727 当前线程:Thread-0,正在运行
2023-08-23 17:58:03:726 当前线程:main,正在运行
2023-08-23 17:58:03:727 当前线程:Thread-0,正在运行
2023-08-23 17:58:03:727 当前线程:main,正在运行
2023-08-23 17:58:03:728 当前线程:Thread-0,正在运行
2023-08-23 17:58:03:728 当前线程:main,正在运行
2023-08-23 17:58:03:728 当前线程:Thread-0,正在运行
2023-08-23 17:58:03:728 当前线程:main,正在运行
2023-08-23 17:58:03:728 当前线程:main,正在运行

从执行时间上可以看到,main线程和Thread-0线程交替运行,效果十分明显!

所谓的多线程,其实就是两个及以上线程的代码可以同时运行,而不必一个线程需要等待另一个线程内的代码执行完才可以运行。

对于单核 CPU 来说,是无法做到真正的多线程的;但是对于多核 CPU 来说,在一段时间内,可以执行多个任务的,由于 CPU 执行代码时间很快,所以两个线程的代码交替执行看起来像是同时执行的一样,具体执行某段代码多少时间,就和分时机制系统有关了。

分时机制系统,简单的说,就是将 CPU 时间划分为多个时间片,操作系统以时间片为单位来执行各个线程的代码,越好的 CPU 分出的时间片越小。

例如某个时段, CPU 将 1 秒划分成 50 个时间片,1 个时间片耗时 20 ms,每个时间片均进行线程切换,也就是说 1 秒可以执行 50 个任务,给人的感觉好像计算机能同时处理多件事情,其实是 CPU 执行任务速度太快给人产生的错觉感。

3.2、实现 Runnable 接口,然后通过 Thread 类来启动介绍
/*** 实现 Runnable 接口*/
public class Thread2 implements Runnable{@Overridepublic void run() {for (int i = 0; i < 5; i++) {String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(new Date());System.out.println(time + " 当前线程:" + Thread.currentThread().getName() + ",正在运行");}}
}
/*** 创建一个测试类*/
public class ThreadTest2 {public static void main(String[] args) {// 通过一个Thread来启动线程Thread thread2 = new Thread(new Thread2());thread2.start();for (int i = 0; i < 5; i++) {String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(new Date());System.out.println(time + " 当前线程:" + Thread.currentThread().getName() + ",正在运行");}}
}

输出结果:

2023-08-23 18:30:28:664 当前线程:Thread-0,正在运行
2023-08-23 18:30:28:666 当前线程:Thread-0,正在运行
2023-08-23 18:30:28:666 当前线程:Thread-0,正在运行
2023-08-23 18:30:28:664 当前线程:main,正在运行
2023-08-23 18:30:28:666 当前线程:Thread-0,正在运行
2023-08-23 18:30:28:667 当前线程:Thread-0,正在运行
2023-08-23 18:30:28:668 当前线程:main,正在运行
2023-08-23 18:30:28:668 当前线程:main,正在运行
2023-08-23 18:30:28:668 当前线程:main,正在运行
2023-08-23 18:30:28:668 当前线程:main,正在运行

效果跟上面介绍的一样,如果循环的打印次数越多,效果越明显!

四、线程状态

下图是一张从操作系统角度划分的线程模型状态!

线程被分为五种状态,各个状态说明如下:

  • 1.新建状态:表示创建了一个新的线程对象,例如Thread thread = new Thread()
  • 2.就绪状态:比如调用线程的start()方法,就会处于就绪状态,也被称为可执行状态,随时可能被 CPU 调度执行
  • 3.运行状态:获得了 CPU 时间片,执行程序代码。需要注意的是,线程只能从就绪状态进入到运行状态
  • 4.阻塞状态:因为某种原因出现了阻塞,线程放弃对 CPU 的使用权,停止执行,直到阻塞事件结束,重新进入就绪状态才有可能再次被 CPU 调度。
  • 5.结束状态:线程里面的方法正常执行结束或者因为某种异常退出了,则该线程结束生命周期

针对操作系统的线程模型,Java 进行部分封装和扩充,JVM 中的线程状态总共有六种,它们之间的关系,可以用如下图来表示:

各个状态说明如下:

  • 1.新建状态(NEW):新创建了一个线程对象
  • 2.运行状态(RUNNABLE):Java 线程中将就绪状态和运行中两种状态,笼统的称为“运行”。线程对象创建后,调用了该对象的start()方法,该线程处于就绪状态,获得 CPU 时间片后变为运行中状态
  • 3.阻塞状态(BLOCKED):因为某种原因,线程放弃对 CPU 的使用权,停止执行,直到进入就绪状态才有可能再次被 CPU 调度。比如线程在获得synchronized同步锁失败后,会把线程放入锁池中,线程进入同步阻塞状态。
  • 4.等待状态(WAITING):处于这种状态的线程不会被分配 CPU 执行时间,它们要等待被显式地唤醒,否则会处于无限期等待的状态。比如运行状态的线程执行wait方法,会把线程放在等待队列中,直到被唤醒或者因异常自动退出
  • 5.超时等待状态(TIMED_WAITING):处于这种状态的线程不会被分配 CPU 执行时间,不过无须无限期等待被其他线程显式地唤醒,在到达一定时间后它们会自动唤醒。比如运行状态的线程执行Thread.sleep(1000)方法,当到达目标时间后,会自动唤醒或者因异常自动退出
  • 6.终止状态(TERMINATED):表示该线程已经执行完毕,处于终止状态的线程不具备继续运行的能力

五、小结

本文主要围绕进程和线程的一些基础知识,进行简单的入门知识总结。

线程的特征和进程差不多,进程有的它基本都有。

相对于进程而言,线程更加的轻量化,主要承担任务的执行工作,优点如下:

  • 一个进程中可以同时拥有多个线程,这些线程共享该进程的资源。我们知道进程间的通信必须请求操作系统服务(因为 CPU 要切换到内核态),开销很大。而同进程下的线程间通信,无需操作系统干预,开销更小
  • 线程间可以并发执行任务,线程间的并发比进程的开销更小,系统并发性更好
  • 在多 CPU 环境下,各个线程也可以分派到不同的 CPU 上并行执行
  • 通过多线程编程,可以显著的提升程序任务的执行效率

不过线程也有缺点:

  • 当程序编程不合理,多个线程发生较长时间的等待或资源竞争时,可能会出现死锁
  • 等候使用共享资源时可能会造成程序的运行速度变慢。这些共享资源主要是独占性的资源,如打印机、IO 设备等

总的来说,进程和线程各有各优势,站在操作系统的设计角度而言,可以归结为以下几点:

  • 采用多进程方式,可以保证多个任务同时运行;
  • 采用多线程方式,可以将单个任务分成不同的部分进行执行;
  • 提供协调机制,防止进程之间和线程之间产生冲突,同时允许进程之间和线程之间共享资源,以充分的利用系统资源

整篇内容难免有描述不对的地方,欢迎网友留言指出!

六、参考

1、飞天小牛肉 - 五分钟扫盲:进程与线程基础必知

2、潘建南 - Java线程的6种状态及切换

写到最后

不会有人刷到这里还想白嫖吧?点赞对我真的非常重要!在线求赞。加个关注我会非常感激!

相关文章:

并发编程系列(一) -多线程技术快速入门

最近对 Java 并发编程技术知识进行了重新整理&#xff0c;再次献上文章合集索引&#xff0c;感兴趣的小伙伴可以直接点击如下地址快速阅读。 并发编程系列(一) -多线程技术快速入门并发编程系列(二) -Thread类介绍并发编程系列(三) -synchronized关键字介绍并发编程系列(四) -v…...

单元测试入门和mockup

Java 新手入门&#xff1a;Java单元测试利器&#xff0c;Mock详解_java mock-CSDN博客 这个是典型的before when assert三段式&#xff0c;学一下单测思路 这个没有动态代理&#xff0c;所以是直接class(对比下面) Jmockit使用笔记_增加代码覆盖率_覆盖try catch_使用new Mock…...

蓝桥杯(Java)(ing)

Java前置知识 输入流&#xff1a; &#xff08;在Java面向对象编程-CSDN博客里面有提过相关知识------IO流&#xff09; // 快读快写 static BufferedReader in new BufferedReader(new InputStreamReader(System.in)); static BufferedWriter out new BufferedWriter(new…...

【Linux-多线程】线程互斥(锁和它的接口等)

一、线程互斥 我们把多个线程能够看到的资源叫做共享资源&#xff0c;我们对共享资源进行保护&#xff0c;就是互斥 1.多线程访问问题 【示例】见一见多线程访问问题&#xff0c;下面是一个抢票的代码&#xff0c;共计票数10000张&#xff0c;4个线程去抢 之前我们展示过封…...

[江科大STM32] 第五集快速建立STM32工程模板——笔记

保存&#xff0c;进去选芯片型号&#xff0c;我们是F10C8T6 一个MD&#xff0c;还有所有.c.h 这里所有文件 这里所有文件...

流水线并行举例说明;GPU 的细粒度问题

GPU 的细粒度与模型并行和流水线并行关系 使用模型并行和流水线并行之后会涉及到一个模型切分细粒度的问题,先切分多头(并行执行),每一个多头在切分不同阶段(串行执行)。这种情况下GPU的细粒度是多少 在这种模型并行和流水线并行结合且按多头和阶段切分的情况下,GPU 的…...

如何确保Kafka集群的高可用?

大家好&#xff0c;我是锋哥。今天分享关于【如何确保Kafka集群的高可用&#xff1f;】面试题。希望对大家有帮助&#xff1b; 如何确保Kafka集群的高可用&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 要确保 Kafka 集群 的高可用性&#xff0c;需要…...

计算机毕业设计Python+Spark考研预测系统 考研推荐系统 考研数据分析 考研大数据 大数据毕业设计 大数据毕设

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

Oracle SqlPlus常用命令简介

参考资料 【SQL*Plus】SETシステム変数の設定前後の具体例 目录 一. 执行系命令1.1 执行系统命令1.2 执行sql脚本文件1.2.1 在数据库中执行sql脚本1.2.2 通过sqlplus执行sql脚本 二. show命令2.1 显示SqlPlus中的全部环境变量2.2 显示指定环境变量的设置 三. 时间显示3.1 set …...

8.若依系统监控与定时任务

帮助开发者和运维快速了解应用程序的性能状态。 数据监控 定时任务 实现动态管理任务。 需求&#xff1a;每间隔5s&#xff0c;控制台输出系统时间。 新建的任务类必须在指定目录ruoyi-quartz模块下的task包下。 状态设置为启动 执行策略 场景&#xff1a;比如一个任务每个…...

《计算机组成及汇编语言原理》阅读笔记:p160-p176

《计算机组成及汇编语言原理》学习第 12 天&#xff0c;p160-p176 总结&#xff0c;总计 17 页。 一、技术总结 1.PowerPC (1)programming model(mode) As in most modern computers, there are at least two separate views of the system (formally called programming m…...

TCP网络编程(三)—— 客户端的编写/服务器端和客户端的通信

上篇文章我们学习了TCP的服务器端模式的编写&#xff0c;这篇文章我们将开始编写客户端的代码&#xff0c;完成服务器端和客户端的通信。完整代码和演示在文章的后面。 和服务器端不同&#xff0c;在客户端我们只需要服务器端的套接字和服务器端的地址和端口&#xff0c;用于向…...

如何在谷歌浏览器中使用自定义模板

作为最常用的网络浏览器之一&#xff0c;谷歌浏览器不仅提供了强大的功能&#xff0c;还允许用户通过各种方式自定义其外观和功能。其中&#xff0c;使用自定义模板可以极大地提升用户体验&#xff0c;无论是更改浏览器的外观还是优化网页显示效果。本文将详细介绍如何在谷歌浏…...

Day2 微服务 网关路由转发、网关登录校验、配置管理

目录 1.网关路由转发 1.1 网关 1.2 快速入门 1.2.1 创建项目 1.2.2 引入依赖 1.2.3 启动类 1.2.4 配置路由 1.2.5 测试 1.3 路由过滤 2.网关登录校验 2.1 鉴权思路分析 2.2 网关过滤器 2.3 自定义过滤器 2.3.1 自定义GatewayFilter 2.3.2 自定义GlobalFilter 2.4 登录校验 2.4.…...

Android 旋转盘导航栏

1.直接上源码&#xff1a; package com.you.arc;import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Point; import android.graphics.RectF; import android.support…...

空域降噪、频域降噪和时域降噪

目录 算法原理&#xff1a; 1.图像噪声 2.图像中常见的噪声的类型 3.不同域的定义 4.空域降噪 4.1.空域降噪的定义&#xff1a; 4.2.思想核心&#xff1a; 4.3.局部的线性算法 高斯降噪 4.4.非局部算法 5.频域降噪 傅里叶降噪&#xff1a; 小波降噪&#xff1a; …...

Cornerstone3D:了解Nifti文件,并查看元数据

Nifti 全称Neuroimaging Informatics Technology Initiative是一种专为存储医学和神经影像数据而设计的文件格式。设计目的是高效的存储三维或四维图像数据&#xff0c;同时将相关的元数据紧凑地嵌入文件中。Nifti文件的组成&#xff1a;头信息&#xff08;元数据&#xff09;…...

设计模式の状态策略责任链模式

文章目录 前言一、状态模式二、策略模式三、责任链模式 前言 本篇是关于设计模式中的状态模式、策略模式、以及责任链模式的学习笔记。 一、状态模式 状态模式是一种行为设计模式&#xff0c;核心思想在于&#xff0c;使某个对象在其内部状态改变时&#xff0c;改变该对象的行为…...

DevOps流程CICD之Jenkins使用操作

一、jenkins的docker-compose安装部署 请参考 jenkins的docker安装部署配置全网最详细教程-CSDN博客 二、创建repository 三、创建ssh 四、创建视图 五、创建任务 六、配置gitlab钩子 七、自动构建部署CI/CD验证...

【玩转23种Java设计模式】行为型模式篇:备忘录模式

软件设计模式&#xff08;Design pattern&#xff09;&#xff0c;又称设计模式&#xff0c;是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 汇总目录链接&…...

Unity Shader TexelSize的意义

TexelSize在制作玻璃折射效果时会用到。 // Get the normal in tangent space fixed3 bump UnpackNormal(tex2D(_BumpMap, i.uv.zw)); // Compute the offset in tangent space float2 offset bump.xy * _Distortion * _RefractionTex_TexelSize.xy; i.scrPos.xy offset * i…...

三、STM32MP257系列之定制Yocto Machine

文章目录 STM32MP257系列之定制的Yocto Machine1. TFA 定制2. OPTEE OS定制3. Uboot 定制3.1 创建 board3.2 创建 board的头文件3.3 创建 board的配置文件3.4 添加我们自己的dtb文件3.5 生成新patch打包到uboot recipe中3.6 修改yocto中的配置 4. Kernel 定制4.1 定制设备树 5.…...

小程序信息收集(小迪网络安全笔记~

免责声明&#xff1a;本文章仅用于交流学习&#xff0c;因文章内容而产生的任何违法&未授权行为&#xff0c;与文章作者无关&#xff01;&#xff01;&#xff01; 附&#xff1a;完整笔记目录~ ps&#xff1a;本人小白&#xff0c;笔记均在个人理解基础上整理&#xff0c;…...

使用 Docker 搭建 Drogon 框架

使用 Docker 搭建 Drogon 框架 Drogon 是一个基于 C 的高性能 Web 框架&#xff0c;支持异步 I/O 和协程。使用 Docker 可以快速搭建 Drogon 开发环境&#xff0c;避免依赖冲突和配置问题。 以下是使用 Docker 搭建 Drogon 框架的详细步骤&#xff1a; 1. 准备工作 安装 Doc…...

【Linux报告】实训一:GNME桌面环境的设置及应用

实训一&#xff1a;GNME桌面环境的设置及应用 【练习1】在图形模式和文本模式下登录Linux系统。 1、开启Linux虚拟机。 答&#xff1a;打开此虚拟机如图所示 2、观察屏幕上显示的启动信息。 3、当系统启动到图形界面时&#xff0c;用普通用户身份登录。 答&#xff1a;如图…...

活动预告 |【Part1】Microsoft Azure 在线技术公开课:基础知识

课程介绍 参加“Azure 在线技术公开课&#xff1a;基础知识”活动&#xff0c;培养有助于创造新的技术可能性的技能并探索基础云概念。参加我们举办的本次免费培训活动&#xff0c;扩充自身的云模型和云服务类型知识。你还可以查看以计算、网络和存储为核心的 Azure 服务。 活…...

vulnhub靶场【Hogwarts】之bellatrix

前言 靶机&#xff1a;hotwarts-dobby&#xff0c;ip地址为192.168.1.69 攻击&#xff1a;kali&#xff0c;ip地址为192.168.1.16 都采用虚拟机&#xff0c;网卡为桥接模式 主机发现 使用arp-scan -l或netdiscover -r 192.168.1.1/24扫描发现主机 信息收集 使用nmap扫描端…...

移动 APP 设计规范参考

一、界面设计规范 布局原则&#xff1a; 内容优先&#xff1a;以内容为核心进行布局&#xff0c;突出用户需要的信息&#xff0c;简化页面导航&#xff0c;提升屏幕空间利用率.一致性&#xff1a;保持界面元素风格一致&#xff0c;包括颜色、字体、图标等&#xff0c;使用户在…...

HarmonyOS:@Require装饰器:校验构造传参

一、前言 Require是校验Prop、State、Provide、BuilderParam和普通变量(无状态装饰器修饰的变量)是否需要构造传参的一个装饰器。 说明 从API version 11开始对Prop/BuilderParam进行校验。 从API version 11开始&#xff0c;该装饰器支持在元服务中使用。 从API version 12开…...

github提交不上去,网络超时问题解决

问题出现的原因&#xff1a; DNS服务器数据不同步&#xff0c;github的服务器发送迁移&#xff0c;在本地缓存的ip地址现在无效了。 解决方案&#xff1a; 1&#xff09;点击这里&#xff0c;查询github.com最新的ip地址 2.0&#xff09;编辑linux系统地址缓存文件&#x…...