《面试专题-----经典高频面试题收集四》解锁 Java 面试的关键:深度解析并发编程进阶篇高频经典面试题(第四篇)

目录

  • 第六章(并发编程进阶)
    • 1.并发编程的三要素分别解释一下,举个简单的例子
    • 2.说下你知道的调度算法,比如进程间的调度
    • 3.常见的线程间的调度算法是怎么样的,java是哪种
    • 4.日常开发中用过java中的哪些锁?分别解释下
    • 5.写一个多线程死锁的例子
    • 6.设计一个简单的不可重入锁
    • 7.设计一个简单的重入锁

该篇博客接着《面试专题-----经典高频面试题收集三》,如需了解之前的blog可前往主页面试专栏查阅

第六章(并发编程进阶)

1.并发编程的三要素分别解释一下,举个简单的例子

原⼦性:

⼀个不可再被分割的颗粒,原⼦性指的是⼀个或多个操作要么全部执⾏成功要么全部执⾏失败,期间不能被中断,也不存在上下⽂切换,线程切换会带来原⼦性的问题

int num = 1; // 原⼦操作

num++; // ⾮原⼦操作,从主内存读取num到线程⼯作内存,进⾏ +1,再把num写到主内存, 除⾮⽤原⼦类,即java.util.concurrent.atomic⾥的原⼦变量类

解决办法:可以⽤synchronized 或 Lock(⽐如ReentrantLock) 来把这个多步操作“变成”原⼦操作,但是volatile,前⾯有说到不能修饰有依赖值的情况

有序性:

程序执⾏的顺序按照代码的先后顺序执⾏,因为处理器可能会对指令进⾏重排序 JVM在编译java代码或者CPU执⾏JVM字节码时,对现有的指令进⾏重新排序,主要⽬的是优化运⾏效率(不改变程序结果的前提)

可⻅性:

⼀个线程A对共享变量的修改,另⼀个线程B能够⽴刻看到

// 线程 A 执⾏

int num = 0;

// 线程 A 执⾏

num++;

// 线程 B 执⾏

System.out.print(“num的值:” + num);

线程A执⾏ i++ 后再执⾏线程 B,线程 B可能有2个结果,可能是0和1。 因为 i++ 在线程A中执⾏运算,并没有⽴刻更新到主内存当中,⽽线程B就去主内存当中读取并打 印,此时打印的就是0;也可能线程A执⾏完成更新到主内存了,线程B的值是1。

所以需要保证线程的可⻅性 synchronized、lock和volatile能够保证线程可⻅性

2.说下你知道的调度算法,比如进程间的调度

先来先服务调度算法: 按照作业/进程到达的先后顺序进⾏调度,即:优先考虑在系统中等待时间最⻓的作业,排在⻓进程后的短进程的等待时间⻓,不利于短作业/进程

短作业优先调度算法: 短进程/作业(要求服务时间最短)在实际情况中占有很⼤⽐例,为了使得它们优先执⾏,对⻓作业不友好

⾼响应⽐优先调度算法: 在每次调度时,先计算各个作业的优先权:优先权=响应⽐=(等待时间+要求服务时间)/ 要求服务时间, 因为等待时间与服务时间之和就是系统对该作业的响应时间,所以优先权=响应⽐=响应 时间/要求服务时间,选择优先权⾼的进⾏服务需要计算优先权信息,增加了系统的开销

时间⽚轮转调度算法: 轮流的为各个进程服务,让每个进程在⼀定时间间隔内都可以得到响应 由于⾼频率的进程切换,会增加了开销,且不区分任务的紧急程度

优先级调度算法: 根据任务的紧急程度进⾏调度,⾼优先级的先处理,低优先级的慢处理 如果⾼优先级任务很多且持续产⽣,那低优先级的就可能很慢才被处理

3.常见的线程间的调度算法是怎么样的,java是哪种

线程调度是指系统为线程分配CPU使⽤权的过程,主要分两种:

协同式线程调度(分时调度模式):线程执⾏时间由线程本身来控制,线程把⾃⼰的⼯作执⾏完之后,要主动通知系统切换到另外⼀个线程上。最⼤好处是实现简单,且切换操作对线程⾃⼰是可知的,没啥线程同步问题。坏处是线程执⾏时间不可控制,如果⼀个线程有问题,可能⼀直阻塞在那⾥

抢占式线程调度:每个线程将由系统来分配执⾏时间,线程的切换不由线程本身来决定(Java中,Thread.yield()可以让出执⾏时间,但⽆法获取执⾏时间)。线程执⾏时间系统可控,也不会有⼀个线程导致整个进程阻塞

Java线程调度就是抢占式调度,优先让可运⾏池中优先级⾼的线程占⽤CPU,如果可运⾏池中的线程优先级相同,那就随机选择⼀个线程 所以我们如果希望某些线程多分配⼀些时间,给⼀些线程少分配⼀些时间,可以通过设置线程优先级来完成。

JAVA的线程的优先级,以1到10的整数指定。当多个线程可以运⾏时,VM⼀般会运⾏最⾼优先级的线 程(Thread.MIN_PRIORITY⾄Thread.MAX_PRIORITY)

在两线程同时处于就绪runnable状态时,优先级越⾼的线程越容易被系统选择执⾏。但是优先级并不是100%可以获得,只不过是机会更⼤⽽已。

有⼈会说,wait,notify不就是线程本身控制吗? 其实不是,wait是可以让出执⾏时间,notify后⽆法获取执⾏时间,随机等待队列⾥⾯获取⽽已

4.日常开发中用过java中的哪些锁?分别解释下

悲观锁:当线程去操作数据的时候,总认为别的线程会去修改数据,所以它每次拿数据的时候都会上锁,别的线程去拿数据的时候就会阻塞,⽐如synchronized

乐观锁:每次去拿数据的时候都认为别⼈不会修改,更新的时候会判断是别⼈是否回去更新数据,通过版本来判断,如果数据被修改了就拒绝更新,⽐如CAS是乐观锁,但严格来说并不是锁,通过原⼦性来保证数据的同步,⽐如说数据库的乐观锁,通过版本控制来实现,CAS不会保证线程同步,乐观的认为在数据更新期间没有其他线程影响

⼩结:悲观锁适合写操作多的场景,乐观锁适合读操作多的场景,乐观锁的吞吐量会⽐悲观锁多

公平锁:指多个线程按照申请锁的顺序来获取锁,简单来说 如果⼀个线程组⾥,能保证每个线程都能拿到锁 ⽐如ReentrantLock(底层是同步队列FIFO:First Input First Output来实现)

⾮公平锁:获取锁的⽅式是随机获取的,保证不了每个线程都能拿到锁,也就是存在有线程饿死,⼀直拿不到锁,⽐如synchronized、ReentrantLock

⼩结:⾮公平锁性能⾼于公平锁,更能重复利⽤CPU的时间

可重⼊锁:也叫递归锁,在外层使⽤锁之后,在内层仍然可以使⽤,并且不发⽣死锁

不可重⼊锁:若当前线程执⾏某个⽅法已经获取了该锁,那么在⽅法中尝试再次获取锁时,就会获取不到被阻塞

⼩结:可重⼊锁能⼀定程度的避免死锁 synchronized、ReentrantLock 重⼊锁

⾃旋锁:⼀个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环,任何时刻最多只能有⼀个执⾏单元获得锁.

⼩结:不会发⽣线程状态的切换,⼀直处于⽤户态,减少了线程上下⽂切换的消耗,缺点是循环会消耗CPU

常⻅的⾃旋锁:TicketLock,CLHLock,MSCLock

共享锁:也叫S锁/读锁,能查看但⽆法修改和删除的⼀种数据锁,加锁后其它⽤户可以并发读取、查询数据,但不能修改,增加,删除数据,该锁可被多个线程所持有,⽤于资源数据共享

互斥锁:也叫X锁/排它锁/写锁/独占锁/独享锁/ 该锁每⼀次只能被⼀个线程所持有,加锁后任何线程试图再次加锁的线程会被阻塞,直到当前线程解锁。例⼦:如果线程A对 data1 加上排他锁后,则其他线程不能再对 data1 加任何类型的锁,获得互斥锁的线程即能读数据⼜能修改数据

死锁:两个或两个以上的线程在执⾏过程中,由于竞争资源或者由于彼此通信⽽造成的⼀种阻塞的现象,若⽆外⼒作⽤,它们都将⽆法让程序进⾏下去

下⾯三种是Jvm为了提⾼锁的获取与释放效率⽽做的优化 针对Synchronized的锁升级(1.6),锁的状态是通过 对象监视器在对象头中的字段来表明,是不可逆的过程

偏向锁:⼀段同步代码⼀直被⼀个线程所访问,那么该线程会⾃动获取锁,获取锁的代价更低

轻量级锁:当锁是偏向锁的时候,被其他线程访问,偏向锁就会升级为轻量级锁,其他线程会通过⾃旋的形式尝试获取锁,但不会阻塞,且性能会⾼点

重量级锁:当锁为轻量级锁的时候,其他线程虽然是⾃旋,但⾃旋不会⼀直循环下去,当⾃旋⼀定次数的时 候且还没有获取到锁,就会进⼊阻塞,该锁升级为重量级锁,重量级锁会让其他申请的线程进⼊阻塞,性能也会降低

分段锁、⾏锁、表锁

5.写一个多线程死锁的例子

线程在获得了锁A并且没有释放的情况下去申请锁B,这时另⼀个线程已经获得了锁B,在释放锁B之前⼜要先获得锁A,因此闭环发⽣,陷⼊死锁循环

public class DeadLockDemo {  private static String locka = "locka";  private static String lockb = "lockb";  public void methodA(){synchronized (locka){System.out.println("我是A⽅法中获得了锁A "+Thread.currentThread().getName() );//让出CPU执⾏权,不释放锁  try {Thread.sleep(2000);} catch (InterruptedException e) {  ​        e.printStackTrace();}synchronized(lockb){System.out.println("我是A⽅法中获得了锁B "+Thread.currentThread().getName() );}}  }  public void methodB(){synchronized (lockb){System.out.println("我是B⽅法中获得了锁B "+Thread.currentThread().getName());//让出CPU执⾏权,不释放锁  try {Thread.sleep(2000);} catch (InterruptedException e) {  ​        e.printStackTrace();}synchronized(locka){System.out.println("我是B⽅法中获得了锁A "+Thread.currentThread().getName() );}}  }  public static void main(String [] args){System.out.println("主线程运⾏开始运 ⾏:"+Thread.currentThread().getName());  DeadLockDemo deadLockDemo = new DeadLockDemo();  new Thread(()->{  deadLockDemo.methodA();  }).start();  new Thread(()->{  deadLockDemo.methodB();  }).start();  System.out.println("主线程运⾏结束:"+Thread.currentThread().getName());  } }

死锁的4个必要条件

互斥条件:资源不能共享,只能由⼀个线程使⽤

请求与保持条件:线程已经获得⼀些资源,但因请求其他资源发⽣阻塞,对已经获得的资源保持不释放

不可抢占:有些资源是不可抢占的,当某个线程获得这个资源后,系统不能强⾏回收,只能由线程使⽤完⾃⼰释放

循环等待条件:多个线程形成环形链,每个都占⽤对⽅申请的下个资源

只要发⽣死锁,上⾯的条件都成⽴;只要⼀个不满⾜,就不会发⽣死锁

●上面的例子怎么解决死锁,优化下代码

○调整申请锁的范围

○调整申请锁的顺序


public class DeadLockDemo {  private static String locka = "locka";  private static String lockb = "lockb";  public void methodA(){synchronized (locka){System.out.println("我是A⽅法中获得了锁A "+Thread.currentThread().getName() );//让出CPU执⾏权,不释放锁  try {Thread.sleep(2000);} catch (InterruptedException e) {  ​        e.printStackTrace();}}synchronized(lockb){System.out.println("我是A⽅法中获得了锁B "+Thread.currentThread().getName() );}  }  public void methodB(){synchronized (lockb){System.out.println("我是B⽅法中获得了锁B "+Thread.currentThread().getName());//让出CPU执⾏权,不释放锁  try {Thread.sleep(2000);} catch (InterruptedException e) {  ​        e.printStackTrace();}}synchronized(locka){System.out.println("我是B⽅法中获得了锁A "+Thread.currentThread().getName() );} }  public static void main(String [] args){System.out.println("主线程运⾏开始运 ⾏:"+Thread.currentThread().getName());  DeadLockDemo deadLockDemo = new DeadLockDemo();  new Thread(()->{  deadLockDemo.methodA();  }).start();  new Thread(()->{  deadLockDemo.methodB();  }).start();  System.out.println("主线程运⾏结束:"+Thread.currentThread().getName());  } }

6.设计一个简单的不可重入锁

//不可重⼊锁:若当前线程执⾏某个⽅法已经获取了该锁,那么在⽅法中尝试再次获取锁时,就会获取 不到被阻塞

public class UnreentrantLock {  private boolean isLocked = false;  public synchronized void lock() throws InterruptedException {System.out.println("进⼊lock加锁 "+Thread.currentThread().getName());//判断是否已经被锁,如果被锁则当前请求的线程进⾏等待  while (isLocked){System.out.println("进⼊wait等待 "+Thread.currentThread().getName());wait();}//进⾏加锁  ​     isLocked = true;  }  public synchronized void unlock(){ System.out.println("进⼊unlock解锁 "+Thread.currentThread().getName()); isLocked = false;  //唤醒对象锁池⾥⾯的⼀个线程  notify(); } } public class Main {  private UnreentrantLock unreentrantLock = new UnreentrantLock();  //加锁建议在try⾥⾯,解锁建议在finally  public void methodA(){try {  ​      unreentrantLock.lock();System.out.println("methodA⽅法被调⽤");methodB();} catch (InterruptedException e){  ​      e.fillInStackTrace();} finally {  ​      unreentrantLock.unlock();}  } public void methodB(){try {​      unreentrantLock.lock();System.out.println("methodB⽅法被调⽤");} catch (InterruptedException e){  ​      e.fillInStackTrace();} finally {  ​      unreentrantLock.unlock();}  }  public static void main(String [] args){  //演示的是同个线程  new Main().methodA();  } } 

//同⼀个线程,重复获取锁失败,形成死锁,这个就是不可重⼊锁

7.设计一个简单的重入锁

//可重入锁:也叫递归锁,在外层使⽤锁之后,在内层仍然可以使⽤,并且不发⽣死锁

public class ReentrantLock {  private boolean isLocked = false;  //⽤于记录是不是重⼊的线程  private Thread lockedOwner = null;  //累计加锁次数,加锁⼀次累加1,解锁⼀次减少1  private int lockedCount = 0;  public synchronized void lock() throws InterruptedException {System.out.println("进⼊lock加锁 "+Thread.currentThread().getName());Thread thread = Thread.currentThread();//判断是否是同个线程获取锁, 引⽤地址的⽐较  while (isLocked && lockedOwner != thread ){System.out.println("进⼊wait等待 "+Thread.currentThread().getName());System.out.println("当前锁状态 isLocked = "+isLocked);System.out.println("当前count数量 lockedCount = "+lockedCount);wait();}//进⾏加锁  ​      isLocked = true;  ​      lockedOwner = thread;  ​      lockedCount++;  } public synchronized void unlock(){System.out.println("进⼊unlock解锁 "+Thread.currentThread().getName());Thread thread = Thread.currentThread();//线程A加的锁,只能由线程A解锁,其他线程B不能解锁  if(thread == this.lockedOwner){ ​      lockedCount--;if(lockedCount == 0){  ​        isLocked = false;  ​        lockedOwner = null;//唤醒对象锁池⾥⾯的⼀个线程  notify();}}  } } public class Main {  private ReentrantLock reentrantLock = new ReentrantLock();  //加锁建议在try⾥⾯,解锁建议在finally  public void methodA(){  try {  ​     reentrantLock.lock();System.out.println("methodA⽅法被调⽤");methodB();  } catch (InterruptedException e){  ​     e.fillInStackTrace();  } finally { ​     reentrantLock.unlock();  }  }  public void methodB(){  try {  ​     reentrantLock.lock();System.out.println("methodB⽅法被调⽤");  } catch (InterruptedException e){  ​     e.fillInStackTrace();  } finally {  ​     reentrantLock.unlock();  }  } public static void main(String [] args){  for(int i=0 ;i<10;i++){//演示的是同个线程  new Main().methodA();  }  } }## 8.对sychronized了解吗,介绍下对它的理解synchronized是解决线程安全的问题,常⽤在 同步普通⽅法、静态⽅法、代码块 中 ⾮公平、可重⼊ 每个对象有⼀个锁和⼀个等待队列,锁只能被⼀个线程持有,其他需要锁的线程需要阻塞等待。锁被释放后,对象会从队列中取出⼀个并唤醒,唤醒哪个线程是不确定的,不保证公平性 两种形式: 1.⽅法:⽣成的字节码⽂件中会多⼀个 ACC_SYNCHRONIZED 标志位,当⼀个线程访问⽅法时,会去检查是否存在ACC_SYNCHRONIZED标识,如果存在,执⾏线程将先获取monitor,获取成功之后才能执⾏⽅法体,⽅法执⾏完后再释放monitor。在⽅法执⾏期间,其他任何线程都⽆法再获得同⼀个monitor对象,也叫隐式同步 2.代码块:加了 synchronized 关键字的代码段,⽣成的字节码⽂件会多出 monitorenter 和 monitorexit 两条指令,每个monitor维护着⼀个记录着拥有次数的计数器, 未被拥有的monitor的该计数器为0,当⼀个线程获执⾏monitorenter后,该计数器⾃增1;当同⼀个线程执⾏monitorexit指令的时候,计数器再⾃减1。当计数器为0的时候,monitor将被释放.也叫显式同步 两种本质上没有区别,底层都是通过monitor来实现同步, 只是⽅法的同步是⼀种隐式的⽅式来实现,⽆需通过字节码来完成有得到锁的资源进⼊Block状态,涉及到操作系统⽤户模式和内核模式的切换,代价⽐较⾼jdk1.6进⾏了优化,增加了从偏向锁到轻量级锁再到重量级锁的过渡,但是在最终转变为重量级锁之后,性 能仍然较低## 9.了解CAS吗,解释一下全称是Compare And Swap,即⽐较再交换,是实现并发应⽤到的⼀种技术 底层通过Unsafe类实现原⼦性操作。操作包含三个操作数:内存地址(V)、预期原值(A)和新值 (B)。 如果内存位置的值(V)与预期原值相(A)匹配,那么处理器会⾃动将该位置值更新为新值 ,若果在第⼀轮循环中,a线程获取地址⾥⾯的值(V)被b线程修改了,那么a线程需要⾃旋,到下次循环才有可能机会执⾏。CAS这个是属于乐观锁,性能较悲观锁有很⼤的提⾼ AtomicXXX 等原⼦类底层就是CAS实现,⼀定程度⽐synchonized好,因为后者是悲观锁## 10.CAS会存在什么比较严重的问题1、⾃旋时间⻓CPU利⽤率增加,CAS⾥⾯是⼀个循环判断的过程,如果线程⼀直没有获取到状态,cpu资源会⼀直被占⽤ 2、存在ABA问题11.什么是ABA问题,如何避免如果⼀个变量V初次读取是A值,并且在准备赋值的时候也是A值,那就能说明A值没有被修改过吗?其实是不能的,因为变量V可能被其他线程改回A值,结果就是会导致CAS操作误认为从来没被修改过,从⽽赋值给V 给变量加⼀个版本号即可,在⽐较的时候不仅要⽐较当前变量的值 还需要⽐较当前变量的版本号。 在java5中,已经提供了AtomicStampedReference来解决问题,检查当前引⽤是否等于预期引 ⽤,其次检查当前标志是否等于预期标志,如果都相等就会以原⼦的⽅式将引⽤和标志都设置为新值

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

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

相关文章

Centos7 两种方式安装 MySQL5.7 步骤 yum 、本地 tar 文件

一、使用 yum 源方式安装 1、卸载系统自带 mariadb MariaDB Server 是最流行的开源 关系型数据库 之一。它由 MySQL 的原始开发者制作&#xff0c;并保证保持开源。 在 CentOS 7 中默认安装有 MariaDB 可忽略&#xff0c;安装完成之后可以直接覆盖掉 MariaDB。 查看并卸载系统…

如何在 Spring Boot 中配置日志记录?

在Spring Boot中配置日志记录是一项关键任务&#xff0c;因为良好的日志记录是应用程序开发和维护的必要组成部分。Spring Boot采用了一种灵活且强大的方式来管理日志&#xff0c;允许开发人员使用不同的日志框架&#xff0c;并提供了易于配置的选项。下面详细介绍在Spring Boo…

新概念英语第二册(39) 上

【New words and expressions】生词和短语&#xff08;10&#xff09; operation n. 手术 successful adj. 成功的 following adj. 下一个 patient n. 病人 alone …

openssl3.2/test/certs - 004 - cross root and root cross cert

文章目录 openssl3.2/test/certs - 004 - cross root and root cross cert概述笔记END openssl3.2/test/certs - 004 - cross root and root cross cert 概述 索引贴 openssl3.2 - 官方demo学习 - test - certs 笔记 // \file my_openssl_linux_log_doc_004.txt // openssl…

【Java 设计模式】行为型之状态模式

文章目录 1. 定义2. 应用场景3. 代码实现结语 状态模式&#xff08;State Pattern&#xff09;是一种行为型设计模式&#xff0c;用于通过将对象的行为封装到不同的状态类中&#xff0c;使得对象在不同的状态下具有不同的行为。状态模式允许对象在内部状态发生改变时改变其行为…

【极数系列】Flink项目入门搭建(03)

【极数系列】Flink项目入门搭建&#xff08;03&#xff09; 引言 gitee地址&#xff1a;https://gitee.com/shawsongyue/aurora.git 源码直接下载可运行&#xff0c;模块&#xff1a;aurora_flink Flink 版本&#xff1a;1.18.0 Jdk 版本&#xff1a;11 1.创建mavenx项目 2.…

清越 peropure·AI 国内版ChatGP新功能介绍

当OpenAI发布ChatGPT的时候,没有人会意识到,新一代人工智能浪潮将给人类社会带来一场眩晕式变革。其中以ChatGPT为代表的AIGC技术加速成为AI领域的热门发展方向,推动着AI时代的前行发展。面对技术浪潮,清越科技(PeroPure)立足多样化生活场景、精准把握用户实际需求,持续精确Fin…

SpringBoot+Vue充电桩管理系统 附带详细运行指导视频

文章目录 一、项目演示二、项目介绍三、运行截图四、主要代码1. 分页获取预约数据代码2.保存预约信息代码3.修改订单状态代码 一、项目演示 项目演示地址&#xff1a; 视频地址 二、项目介绍 项目描述&#xff1a;这是一个基于SpringBootVue框架开发的充电桩管理系统。首先&…

【报错解决】anaconda: Read timed out.

报错描述 在anaconda的虚拟环境中用pip或conda下载安装包时&#xff0c;遇到如下报错&#xff0c;具体报错内容如下所示&#xff1a; raise ReadTimeoutError(self._pool, None, "Read timed out.") pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnect…

网络安全的使命:守护数字世界的稳定和信任

在数字化时代&#xff0c;网络安全的角色不仅仅是技术系统的守护者&#xff0c;更是数字社会的信任保卫者。网络安全的使命是保护、维护和巩固数字世界的稳定性、可靠性以及人们对互联网的信任。本文将深入探讨网络安全是如何履行这一使命的。 第一部分&#xff1a;信息资产的…

怎么给wordpress网站底部页脚添加备案号和链接?

以前“WordPress后台 >> 常规”最底部是有一个ICP备案号的&#xff0c;我们只需要填写备案号并保存更改即可让WordPress自带主题底部显示ICP备案号&#xff0c;但是现在新版本的WordPress已经没有了这个ICP备案号选项&#xff0c;而且也无法直接添加公安联网备案号&#…

vscode debug

需要对GitHub上的工程debug。 所以花时间看了下,参考了bili视频和chatgpt的解答。 chatgpt给的步骤 要在 VS Code 中调试 C++ 项目,可以按照以下步骤进行设置和操作: 确保已安装 C++ 扩展:在 VS Code 中选择 “Extensions”(或使用快捷键 Ctrl+Shift+X),搜索并安装官…

Typecho后台无法登录显示503 service unavailable问题及处理

一、Typecho 我的博客地址&#xff1a;https://www.aomanhao.top 使用老薛主机动态Typecho博客框架handsome主题的搭配&#xff0c;文章内容可以异地网页更新&#xff0c;可以听后台背景音乐&#xff0c;很好的满足我的痛点需求&#xff0c;博客部署在云端服务器访问响应较快…

mac intel jdk安装与配置

jdk地址下载 https://www.oracle.com/java/technologies/downloads/ https://repo.huaweicloud.com/java/jdk/8u201-b09/ 安装后 下载完成之后打开终端 注意如果是第一次配置环境变量需要创建.bash_profile文件。&#xff08;注意&#xff1a;touch后面有空格&#xff09; to…

dpkt库多次循环读取PCAP文件中的完整数据方法

dpkt库多次循环读取PCAP文件中的完整数据方法 1. 问题 使用下面方法,结果发现第一次for循环和第二次for循环进去time_stamp不一样,而我需要两次都读取完整数据,所以就需要找方法解决一下这个问题。 fp = open(22.pcapng, rb) pcap = dpkt.pcapng.Reader(fp)for ts, buf i…

单调栈笔记

单调栈 1.每日温度2.下一个更大元素 I3.下一个更大的元素4.接雨水5.柱状图中最大的矩形 单调栈正如其名字&#xff0c;用一个栈&#xff08;能够实现栈性质的数据结构就行&#xff09;来存储元素&#xff0c;存储在栈中的元素保持单调性&#xff08;单调递增或者是单调递减&…

信息检索与数据挖掘 | (十)线性回归与逻辑回归

文章目录 &#x1f4da;线性回归算法流程&#x1f4da;Bias and variance&#x1f4da;过拟合&欠拟合&#x1f4da;逻辑回归算法流程 &#x1f4da;线性回归算法流程 ybwx 使用loss function L来评估函数的好坏 从而我们要选择使L最小的模型参数w,b 使用梯度下降的方法…

所有博客导航--总结

一、Java相关知识点 1.Java 2实用教程-输入输出数据 2.Java 2实用教程-类型转换运算 3.Java 2实用教程-基本数据类型 4.Java 2 实用教程-标识符与关键字 5.java 2 实用教程-数组 1.基本数据类型与数组第一节 2.基本数据类型与数组第二节 6.Java 2实用教程-运算符与表达…

JAVA 学习 面试(六)数据类型与方法

数据类型 基本数据类型 为什么float3.4报错 3.4 默认是浮点double类型的&#xff0c;如果赋值给float是向下转型&#xff0c;会出现精度缺失&#xff0c;&#xff0c;需要强制转换 Switch支持的数据类型&#xff1f; byte、short、int、char 、 enum 、 String 基本类型与包…

openssl加解密和签名验签步骤操作记录

文章目录 一、AES加解密操作1.1 EBC模式1.2 CBC模式 二、RSA加解密操作三、RSA 加解密和 AES 加解密对比四、RSA签名和验签操作 一、AES加解密操作 1.1 EBC模式 使用 OpenSSL 进行 AES 的 ECB&#xff08;电子密码本&#xff09;模式加解密相对简单。以下是基本步骤&#xff…