java学习--day22(进程线程)

文章目录

      • 1.什么是进程
      • 2.什么是线程
      • 3.线程和进程的区别【面试题】
      • 4.并发和并行
      • 5.创建线程的两种方式【重点】
        • 1.继承Thread
        • 2.实现Runnable接口
      • 6.线程下面的几个方法
      • 7.线程的同步和锁【重要】

1.什么是进程

是独立的运行程序

​ 比如咱们电脑软件,你启动起来以后,他就是一个进程。qq idea

进程需要windows系统的分配。可以获取当前的系统的网卡,内存,显卡等

​ 1.独立性

​ 各个进程之间是相互的独立的互不影响 的。录屏软件和idea没有关系的

​ 2.互斥性

​ 每个软件系统都会分配一个独立端口号,如果启动一个软件以后他的端口号97。

​ 如果再启动另外一个软件,另外一个软件如果端口也是97,这个程序就启动不了,端口被占用的

脑海里面知道开启的软件就是一个进程 即可!!!

2.什么是线程

进程是由多个或者一个线程组成的。每个进程至少得有一个线程的支撑。

脑海里面这样来想,一个进程(qq),qq里面很多个线程在执行。线程的执行

支撑起来了进程的执行。

把一个人比作一个进程,那么你身体里面的细胞就是线程。如果没有细胞。这个人还存在吗?不存在的!!!

进程包含了线程,线程是组成进程的最小基本单位

​ 特性:

​ 1.抢占式运行的【重要】

​ CPU在执行的时候,按照时间片来执行的,单位的时间片是抢占是执行

​ 比如 idea qq 抢占CPU的,比如qq的线程抢到cpu,idea线程等待

​ 我是一个cpu。你们问我问题。75个线程。同时来问我问题吗?不是

​ 抢着问。一个问。然后其他人等待。这个人甚至还没有问完,其他的某一个人

​ 抢到我了,他问我。大概就是效果

​ 2.资源共享性

​ 一个线程可以共享当前CPU, 网卡等

Java程序:

​ 一个Java程序就是一个进程 Demo1 就是一个应用程序 就是一个进程

​ 一个Java程序Demo1里面至少 几个线程?

​ 两个:

​ main主函数线程

​ JVM垃圾回收器线程

3.线程和进程的区别【面试题】

进程是一个应用程序,是独立的
线程是进程中最小的基本单位。
把进程比作生产车间,每个流水线就是一个线程
进程有独立性和互斥性
线程有抢占式资源共享特性

4.并发和并行

并发:同时发生,轮流交替执行

并行:真正意义的同时执行

比如:

​ 你去饭店点了两个菜,生活中拿个筷子轮流夹菜哦这就是并发场景

​ 端起盘子,同时倒到嘴里面,这就是并行场景

5.创建线程的两种方式【重点】

1.继承Thread

创建线程的两种方式

  1. 一个是将一个类声明为Thread的子类。 这个子类应该重写run方法 。 然后可以分配并启动子类的实例。
package com.qfedu.a_thread;// 一个是将一个类声明为Thread的子类。
// 这个子类应该重写run类的方法Thread 。
// 然后可以分配并启动子类的实例。
class MyThread1 extends Thread{@Overridepublic void run() {for (int i = 0; i < 500; i++) {System.out.println("我是myThread1线程:" + i);}}
}
class MyThread2 extends Thread {@Overridepublic void run() {//run方法中写功能代码  就是一个线程中执行的一个功能for (int i = 0; i < 500; i++) {System.out.println("我是mythread2线程:" + i);}}
}
public class Demo1 {public static void main(String[] args) {//官方手册中说,要去实例化Thread的子类,并启动线程MyThread1 myThread1 = new MyThread1();//启动线程 使用start方法  在主线程中开启子线程myThread1.start();MyThread2 myThread2 = new MyThread2();myThread2.start();//现在有几个线程?  3个//一个是MyThread1线程  一个是主线程(main)  一个垃圾回收机制线程for (int i = 0; i < 500; i++) {System.out.println("主函数线程:" + i);}//发现先执行了主线程,然后再执行子线程,然后又执行主线程//这就线程的抢占式的运行//三个线程://你自己吃三盘菜,咋吃?//一盘菜代表一个线程,一盘菜夹一下,随机的吧。//开启一个线程,就是在执行一个任务。//上面这个代码,你们执行结果和我执行的结果一样吗?绝对不一样的//抢占式的,随机执行线程的!!!}
}
练习:main主线程 打印100遍的吃大盘鸡子线程1 打印100遍的吃水煮肉片子线程2 打印100遍的吃毛血旺一定要注意打印的结果,多执行几遍,看看每次执行的结果是否一样!!!
2.实现Runnable接口

另一种方法来创建一个线程是声明实现类Runnable接口。 那个类然后实现了run方法。 然后可以分配类的实例,在创建Thread时作为参数传递,并启动。

package com.qfedu.a_thread;//另一种方法来创建一个线程是声明实现类Runnable接口。
// 那个类然后实现了run方法。 
// 然后可以分配类的实例(创建类的对象),在创建Thread实例时作为参数传递,并启动。
class MyThread3 implements Runnable {@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println("MyThread3:" + i);}}
}
class MyaThread4 implements Runnable {@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println("MyThread4:" + i);}}
}
public class Demo2 {public static void main(String[] args) {MyThread3 myThread3 = new MyThread3();//Thread(Runnable target)  参数是Runnable这个接口对象//分配一个新的 Thread对象。Thread thread = new Thread(myThread3);thread.start();MyaThread4 myaThread4 = new MyaThread4();Thread thread1 = new Thread(myaThread4);thread1.start();for (int i = 0; i < 100; i++) {System.out.println("main主线程:" + i);}//有几个线程做任务的线程  3个 一个是main主线程  一个是MyThread3//一个MyThread4这个线程//可以发现运行的结果是随机执行的!!!}
}

6.线程下面的几个方法

构造方法

Thread()分配一个新的 Thread对象。 无参构造方法
Thread(Runnable target)分配一个新的 Thread对象。 有参构造
Thread(Runnable target, String name)分配一个新的 Thread对象。并起名字

线程方法:

static ThreadcurrentThread()返回对当前正在执行的线程对象的引用
StringgetName()返回此线程的名称。
voidsetName(String name)将此线程的名称更改为等于参数 name
intgetPriority()返回此线程的优先级。
voidsetPriority(int newPriority)更改此线程的优先级。
设置优先并不一定优先,只是增加了执行的概率。最小值是1,最大值是10,默认的是5
static voidsleep(long millis)使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行),具体取决于系统定时器和调度程序的精度和准确性。
package com.qfedu.b_threadfun;class MyThread1 implements Runnable {@Overridepublic void run() {Thread thread = Thread.currentThread();//此时这个thread对象是MyThread1这个线程//对子线程设置名字thread.setName("mythread1子线程");System.out.println(thread.getName());//Thread-0}
}
class MyThread2 implements Runnable {@Overridepublic void run() {Thread thread = Thread.currentThread();System.out.println(thread.getName());//狗蛋}
}
public class Demo1 {public static void main(String[] args) {//currentThread() 获取当前线程对象Thread thread = Thread.currentThread();//现在thread  这个对象是哪个线程?主线程//为啥是main主线程//给main主线程设置名字thread.setName("主线程");//获取的是main主线程的名字,Jvm会给主线程还有其他线程一个默认的名字System.out.println(thread.getName());//main
//        MyThread1 myThread1 = new MyThread1();
//        Thread thread1 = new Thread( myThread1);
//        thread1.start();new Thread(new MyThread1()).start();//Java中默认的主线程叫main  子线程叫Thread-0  Thread-1....//默认的有名字,咱们能不能对线程自定义名字?能//我在启动MyThread2的这个线程的时候顺便起名字MyThread2 myThread2 = new MyThread2();//myThread2线程的名字就叫狗蛋,是在创建线程的时候就已经起好名字了Thread thread1 = new Thread(myThread2, "狗蛋");thread1.start();}
}
package com.qfedu.b_threadfun;class MyThread3 implements Runnable {@Overridepublic void run() {//想看一下MyThread3这个线程的优先级是几Thread thread = Thread.currentThread();thread.setPriority(10);System.out.println(thread.getPriority());for (int i = 0; i < 100; i++) {System.out.println("MyThread3线程:" + i);}}
}
class MyThread4 implements Runnable {@Overridepublic void run() {//想看一下MyThread3这个线程的优先级是几Thread thread = Thread.currentThread();thread.setPriority(1);System.out.println(thread.getPriority());for (int i = 0; i < 100; i++) {System.out.println("MyThread4线程:" + i);}}
}
public class Demo2 {public static void main(String[] args) {//默认的优先级都是5,能不能手动去修改某一个线程的优先级?//可以Thread thread = Thread.currentThread();//主线程的优先级设置1//thread.setPriority(1);//获取主线程的优先级System.out.println(thread.getPriority());//5//优先级  1 ~10  1的优先级最低  10的优先级最高//jvm默认线程的优先级是5
//        for (int i = 0; i < 100; i++) {
//            System.out.println("主线程:" + i);
//        }new Thread(new MyThread3()).start();new Thread(new MyThread4()).start();//所以优先级不要用啦!!!并不一定真正的优先!!!//线程执行的结果不可控!!!很尴尬!!!}
}
package com.qfedu.b_threadfun;class MyThread5 implements Runnable {@Overridepublic void run() {try {//发现 Thread.sleep 有一个运行时异常,//但是发现没有抛出,只有try-catch 为啥?//sleep方法写在了run方法中了,因为//run方法是重写的, 父类的 public abstract void run();//父类有抛出吗?没有抛出,重写是比较严格的//父类没有抛出,子类也同样不能抛出Thread.sleep(10000);//10秒} catch (InterruptedException e) {e.printStackTrace();}for (int i = 0; i < 500; i++) {System.out.println("MyThread5:" + i);}}
}
class MyThread6 implements Runnable {@Overridepublic void run() {for (int i = 0; i < 500; i++) {System.out.println("MyThread6:" + i);}}
}
public class Demo3 {public static void main(String[] args) {new Thread(new MyThread5()).start();new Thread(new MyThread6()).start();//发现运行的结果是不可控的,是随机的抢占式的//咱们接下来学习一个东西叫sleep  让某一个线程睡一会儿//这个线程在睡觉的期间不会去抢占cpu  不执行//现在我让MyTread5睡了一会儿。就意味着绝对MyThread6线程先执行//实现可控的效果//思考:sleep方法再开发的时候敢用不敢用?//不敢用。睡多久你知道吗?睡多久合适?不能确定//cpu最大利用化。不可能让cpu闲置//如果sleep睡眠时间少的话,还是抢占//如果sleep睡眠你时间太长的话,就会cpu就会闲置//没有办法把控的!!! 接下来要学习锁!!!}
}

回顾:

1.新建线程的两种方式1.继承Thread2.实现Runnable接口【开发要用的】代码要自己学会写的!!!
2.线程的方法Thread.currentThread();获取当前线程对象setPriority();设置优先级的getPriority(); 获取当前线程的优先级getName();得到线程的名字setName();设置线程的名字sleep();线程的休眠

7.线程的同步和锁【重要】

为什么要进行线程的同步?

Java是允许多线程(多个线程),当多个线程操作同一个资源(咋操作)的时候,会导致得到或者打印的数据不准确。从而发生冲突。咋解决?加同步锁。

美团
淘票票
这个两个线程,都去麦同一场次的票
结果美团卖出去一张1排1列的票
结果淘票票也卖出去了1排1列的票  你感觉合适吗?
就是上面的这种结果!!!不合适的,分享同一个资源的时候,要保证分享资源的数据,合法性!!!分析结果:
package com.qfedu.c_sync;//最理想的状态!!!
//先线程1进入到ticket=50,循环 循环结束以后 此时
//tiket=49了
//循环第二次的时候 线程2抢到资源了 此时ticket=49
//循环 打印49 tiket-- ticket=48了
//循环第三次的时候 线程2 抢到资源了, 此时ticket=48
//打印卖第48张票。ticket--  tiket=47
//线程1又抢到循环
//现在的情况是:有可能两个线程同时进入到while循环
//
class MySync implements Runnable {int ticket = 50;@Overridepublic void run() {//while (true) {//死循环//两个线程都进入到了循环了//此时两个线程所持有的ticket 都是50//但是两个线程都要往下执行//有可能线程1 先执行了sout(50)  线程2在等待哦!!!//线程1执行了--操作并出了循环 线程1ticket = 49//线程1又抢到循环了 sout(49) tiket--//再进入倒这个循环,有可能线程2抢到这个执行权//线程2要往下执行输出语句  ticket=50 打印50if (ticket > 0) {//线程具有抢占式的运行//咱们有没有可能,线程3进入到if语句//此时线程1也进入到if语句了//线程3去打印 卖出了50张票//在线程1里面  ticket=50//线程3又抢到ticket-- 又进入到循环了  ticket = 49//线程3又抢到了ticket-- 又进入倒循环 ticket=48//线程1又抢到资源要执行,执行输出语句  tiekct=50System.out.println(Thread.currentThread().getName() + "卖出了第" + ticket + "票");ticket--;} else {System.out.println("买完了");break;//终止循环!!!}}}
}
public class Demo1 {public static void main(String[] args) {MySync mySync = new MySync();//这三个线程Thread thread1 = new Thread(mySync, "线程1");thread1.start();Thread thread2 = new Thread(mySync, "线程2");thread2.start();Thread thread3 = new Thread(mySync, "线程3");thread3.start();}
}

解决方案:

​ 1.同步方法:使用一个关键字synchronized修饰方法。因为Java对象都有一个内置的锁对象。当使用这个关键字的时候,修饰方法的时候,这个方法就会被锁保护起来被锁锁住

当一个线程进来以后,会立马锁住当前的方法。意味着只有一个线程进来,其他线程都在外面等着。

public synchronized  void run () {}
package com.qfedu.c_sync;//最理想的状态!!!
//先线程1进入到ticket=50,循环 循环结束以后 此时
//tiket=49了
//循环第二次的时候 线程2抢到资源了 此时ticket=49
//循环 打印49 tiket-- ticket=48了
//循环第三次的时候 线程2 抢到资源了, 此时ticket=48
//打印卖第48张票。ticket--  tiket=47
//线程1又抢到循环
//现在的情况是:有可能两个线程同时进入到while循环
//
class MySync1 implements Runnable {int ticket = 50;//对这个run方法加了锁 就意味着只有一个线程进入到run方法中//其他线程都在run方法外面等待@Overridepublic synchronized void run() {//while (true) {//死循环//两个线程都进入到了循环了//此时两个线程所持有的ticket 都是50//但是两个线程都要往下执行//有可能线程1 先执行了sout(50)  线程2在等待哦!!!//线程1执行了--操作并出了循环 线程1ticket = 49//线程1又抢到循环了 sout(49) tiket--//再进入倒这个循环,有可能线程2抢到这个执行权//线程2要往下执行输出语句  ticket=50 打印50if (ticket > 0) {//线程具有抢占式的运行//咱们有没有可能,线程3进入到if语句//此时线程1也进入到if语句了//线程3去打印 卖出了50张票//在线程1里面  ticket=50//线程3又抢到ticket-- 又进入到循环了  ticket = 49//线程3又抢到了ticket-- 又进入倒循环 ticket=48//线程1又抢到资源要执行,执行输出语句  tiekct=50System.out.println(Thread.currentThread().getName() + "卖出了第" + ticket + "票");ticket--;} else {System.out.println("买完了");break;//终止循环!!!}}}
}
public class Demo2 {public static void main(String[] args) {MySync1 mySync = new MySync1();//这三个线程Thread thread1 = new Thread(mySync, "线程1");thread1.start();Thread thread2 = new Thread(mySync, "线程2");thread2.start();Thread thread3 = new Thread(mySync, "线程3");thread3.start();//为啥都是线程1卖出去的票?//很巧  线程1抢到执行权了,进入到run方法中//线程2和线程3在外面等着。//一个循环进来以后,把循环全部执行完!!!//会出现一家独大的情况!!!也是不符合咱们生活场景的!!!//咋解决?咱们 不能方法中加锁,在其他地方加锁}
}

换另外一种解决方法:

​ 同步代码块:就是拥有了synchronized 关键字修饰一个语句块。被修饰的语句块会被加锁。从而实现同步。

语法格式:

synchronized  (this) {被加锁的代码块
}
package com.qfedu.c_sync;//最理想的状态!!!
//先线程1进入到ticket=50,循环 循环结束以后 此时
//tiket=49了
//循环第二次的时候 线程2抢到资源了 此时ticket=49
//循环 打印49 tiket-- ticket=48了
//循环第三次的时候 线程2 抢到资源了, 此时ticket=48
//打印卖第48张票。ticket--  tiket=47
//线程1又抢到循环
//现在的情况是:有可能两个线程同时进入到while循环
//
class MySync2 implements Runnable {int ticket = 500;//对这个run方法加了锁 就意味着只有一个线程进入到run方法中//其他线程都在run方法外面等待@Overridepublic  void run() {//能不能对循环加锁?不能 因为循环加锁以后,还是一个线程循环完,没有任何意义while (true) {//死循环//if语句加了锁以后//就意味着只有一个线程进入到if语句//假如线程1进入if语句了,线程2和线程3就会等待//线程1打印50 并--  ticket变量为49//线程2抢到了49 sout(49) tiket--  48//其他线程再抢!!!//核心业务 加了锁,只让一个线程进入,操作完以后。锁释放掉//然后这三个线程再抢。还只能进一个,再操作核心业务synchronized (this) {//只能让一个线程进入操作,其他线程在外面等待排队if (ticket > 0) {//线程具有抢占式的运行//咱们有没有可能,线程3进入到if语句//此时线程1也进入到if语句了//线程3去打印 卖出了50张票//在线程1里面  ticket=50//线程3又抢到ticket-- 又进入到循环了  ticket = 49//线程3又抢到了ticket-- 又进入倒循环 ticket=48//线程1又抢到资源要执行,执行输出语句  tiekct=50System.out.println(Thread.currentThread().getName() + "卖出了第" + ticket + "票");ticket--;} else {System.out.println("买完了");break;//终止循环!!!}}}}
}
public class Demo3 {public static void main(String[] args) {MySync2 mySync = new MySync2();//这三个线程Thread thread1 = new Thread(mySync, "线程1");thread1.start();Thread thread2 = new Thread(mySync, "线程2");thread2.start();Thread thread3 = new Thread(mySync, "线程3");thread3.start();//为啥都是线程1卖出去的票?//很巧  线程1抢到执行权了,进入到run方法中//线程2和线程3在外面等着。//一个循环进来以后,把循环全部执行完!!!//会出现一家独大的情况!!!也是不符合咱们生活场景的!!!//咋解决?咱们 不能方法中加锁,在其他地方加锁}
}

针对于同步代码块举个例子:

​ 上厕所的时候,有坑位,这个坑位就是资源。

​ 三个人去抢这个资源,如果不加锁的话,会出现问题的?是的。加上锁以后就会保证数据准确性。

案例:

加锁的目的为了保证数据的准确性。
卖电影票:三个线程:淘票票美团猫眼100张票
package com.qfedu.c_sync;class SaleTicket implements Runnable {//声明一个变量票//静态的变量和对象没有关系了private static int ticket = 100;@Overridepublic void run() {//美团while (true) {//美团  猫眼  淘票票synchronized (this) {if (ticket > 0) {//淘票票  和猫眼同时进入到if语句,但是都没有执行ticket--这个操作System.out.println(Thread.currentThread().getName() + "卖出了第" + ticket + "票");//所以会打印 淘票票 100   猫眼100ticket--;} else {System.out.println("卖完了");break;}}}}
}
public class Demo4 {public static void main(String[] args) {SaleTicket saleTicket = new SaleTicket();new Thread(saleTicket, "淘票票").start();new Thread(saleTicket, "美团").start();new Thread(saleTicket, "猫眼").start();//淘票票卖出了第100票//猫眼卖出了第100票//淘票票卖出了第99票//淘票票卖出了第97票//淘票票卖出了第96票//淘票票卖出了第100票//淘票票卖出了第99票//猫眼卖出了第98票//猫眼卖出了第97票}
}

线程就是这样,不可控制,但是可以加锁。让他可控制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/99197.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu LabelMe AI 识别

1.创建虚拟环境 conda create -n labelme python3.9 2.激活虚拟环境 conda activate labelme 3.安装labelme pip install pyqt5 -i https://pypi.tuna.tsinghua.edu.cn/simple pip install pillow -i https://pypi.tuna.tsinghua.edu.cn/simple pip install labelme -i ht…

【数据结构-字符串 三】【字符串转换】字符串解码

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是【字符串转换】&#xff0c;使用【字符串】这个基本的数据结构来实现&#xff0c;这个高频题的站点是&#xff1a;CodeTop&#xff0c;筛选条件为&…

RPC分布式网络通信框架项目

文章目录 对比单机聊天服务器、集群聊天服务器以及分布式聊天服务器RPC通信原理使用Protobuf做数据的序列化&#xff0c;相比较于json&#xff0c;有哪些优点&#xff1f;环境配置使用项目代码工程目录vscode远程开发Linux项目muduo网络库编程示例CMake构建项目集成编译环境Lin…

【计算机网络黑皮书】传输层

【事先声明】 这是对于中科大的计算机网络的网课的学习笔记&#xff0c;感谢郑烇老师的无偿分享 书籍是《计算机网络&#xff08;自顶向下方法 第6版&#xff09;》 需要的可以私信我&#xff0c;无偿分享&#xff0c;课程简介下也有 课程链接 目录 传输服务与协议网络层与传输…

Linux 指令心法(十)`head` 显示文本文件的开头部分

文章目录 命令的概述和用途命令的用法命令行选项和参数的详细说明命令的示例命令的注意事项或提示 命令的概述和用途 head 是一个用于显示文本文件的开头部分的命令。它在 Linux 和 Unix 系统中非常有用&#xff0c;因为它允许用户查看文件的前几行&#xff0c;以便快速预览文…

常见排序算法Java版(待续)

冒泡排序O(n^2) public class Main {public static void main(String[] args) {Random random new Random();int[] nums new int[]{random.nextInt(100), random.nextInt(100), random.nextInt(100), random.nextInt(100), random.nextInt(100), random.nextInt(100)};for (i…

英特尔参与 CentOS Stream 项目

导读红帽官方发布公告欢迎英特尔参与进 CentOS Stream 项目&#xff0c;并表示 “这一举措不仅进一步深化了我们长期的合作关系&#xff0c;也构建在英特尔已经在 Fedora 项目中积极贡献的基础之上。” 目前&#xff0c;CentOS Stream 共包括以下特别兴趣小组&#xff08;SIG&a…

汽车冲压车间的RFID技术设计解决方案

一、RFID技术的基本原理 RFID技术是一种利用非接触式自动识别的技术&#xff0c;通过将RFID标签放置在被识别物品上&#xff0c;并使用RFID读写器对标签进行扫描和识别&#xff0c;实现对物品的自动识别和追踪。RFID标签分为被动式和主动式两种。被动式标签无内置电源&#xf…

23.3 Bootstrap 框架4

1. 轮播 1.1 轮播样式 在Bootstrap 5中, 创建轮播(Carousel)的相关类名及其介绍: * 1. carousel: 轮播容器的类名, 用于标识一个轮播组件. * 2. slide: 切换图片的过渡和动画效果. * 3. carousel-inner: 轮播项容器的类名, 用于包含轮播项(轮播图底下椭圆点, 轮播的过程可以显…

HTTP协议的请求协议和响应协议的组成,HTTP常见的状态信息

HTTP协议 什么是协议 协议实际上是某些人或组织提前制定好的一套规范,大家只要都按照这个规范来就可以做到沟通无障碍 HTTP协议是W3C(万维网联盟组织)制定的一种超文本传输通信协议(发送消息的模板和数据的格式),除了传送字符串,还有声音、视频、图片等流媒体等超文本信息 …

ctfshow-web11(session绕过)

php代码审计&#xff1a; function replaceSpecialChar($strParam){$regex "/(select|from|where|join|sleep|and|\s|union|,)/i";return preg_replace($regex,"",$strParam);} 首先定义了一个函数&#xff0c;主要是使用preg_replace函数对我们提交的内…

拟合平面再思考

0。总结 之前思考了2种拟合平面的方式 1。ransan 随机取样拟合平面 2。特征值分解特征向量&#xff0c;最小特征值就是法向量 其中方法一误差较小&#xff0c;毕竟随机采样的方式可以忽略误差点。而特征值分解的方式如果误差较大&#xff0c;那么得到的结果非常不好 1。扩展…

SpringBoot的创建和使用

优点 快速添加依赖&#xff1b; 内置web容器&#xff1b; 自动装配&#xff1b; idea创建 创建maven项目&#xff08;配置&#xff09; 一定要选择2.x版本的Spring Boot 介绍目录 (有这个注解的SpringBootApplication就是启动类) 删除文件 尝试去运行带有SpringBootApplica…

面向对象设计-UML六种箭头含义

目录 UML概述UML语义UML表示法 六种常用关系标识方法泛化实现依赖关联聚合组合 本文参考文章 https://blog.csdn.net/qq_25091281/article/details/123801862 UML概述 UML (Unified Modeling Language)为面向对象软件设计提供统一的、标准的、可视化的建模语言。适用于描述以…

数学分析:含参变量的积分

同样很多收敛性的证明不是重点&#xff0c;但里面的知识还是需要适当掌握&#xff0c;知道中间的大致思考和解决路径即可。 本质还是极限的可交换性&#xff0c;求导可以换到积分里面去操作。 这里要注意变量的区别&#xff0c;首先积分的被积变量是x&#xff0c;但是函数的变量…

springsecurity

springsecurity 一个安全框架&#xff0c;例如&#xff1a;在进行登录之前&#xff0c;会进行一个拦截&#xff0c;经过安全框架之后&#xff0c;才会跳转到原本要登录的地址 culr:&#xff08;不细写&#xff0c;需另找文档&#xff09; 可以进行登录的操作&#xff08;在git…

git 详解-提升篇

git 冷门使用 承接上一篇 《git 进阶篇》&#xff0c;简单讲解 git 冷门使用方法。 码农常规使用工具 git 偶尔也有非常规操作。例如&#xff1a;提交代码时同事已经更新&#xff0c;但又不想回退本地补丁&#xff1b;或者已经提交补丁需要变更提交日志信息。 作者&#xff1…

[Android]问题解决-Device must be bootloader unlocked

现象 在push文件时&#xff0c;remount命令发生如下报错&#xff1a; $ adb remount Device must be bootloader unlocked解决 1. 打开 开发者模式中的OEM unlocking开关 2. fastboot unlock设置 adb reboot bootloader fastboot flashing unlock根据屏幕提示&#xff0c;…

Android 多线程并发详解

一&#xff0c;基础概念 1.1什么是CPU 中央处理器&#xff08;CPU&#xff09;&#xff0c;是电子计算机的主要设备之一&#xff0c;电脑中的核心配件。其功能主要是解释计算机指令以及处理计算机软件中的数据。CPU是计算机中负责读取指令&#xff0c;对指令译码并执行指令的…

MySQL-锁

MySQL的锁机制 1.共享锁(Shared Lock)和排他锁(Exclusive Lock) 事务不能同时具有行共享锁和排他锁&#xff0c;如果事务想要获取排他锁&#xff0c;前提是行没有共享锁和排他锁。而共享锁&#xff0c;只要行没有排他锁都能获取到。 手动开启共享锁/排他锁&#xff1a; -- 对…