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

【研究生复试】计算机软件工程人工智能研究生复试——资料整理(速记版)——JAVA

1、JAVA
2、计算机网络
3、计算机体系结构
4、数据库
5、计算机租场原理
6、软件工程
7、大数据
8、英文 自我介绍

1. Java

1. == 和 equals的区别

比较基本数据类型是比较的值,引用数据类型是比较两个是不是同一个对象,也就是引用是否指向同
一个对象,地址是否相同,equals本质上也是
,但是可以重写这个方法,比如String和Integer类。

2. 为什么重写equals要重写hashcode?

我个人的理解是,Hash比equals方法的开销要小,速度更快,所以在涉及到hashcode的容器中(比如
HashSet),判断自己是否持有该对象时,会先检查hashCode是否相等,如果hashCode不相等,就会
直接认为不相等,并存入容器中,不会再调用equals进行比较。而hashcode的默认方法是根据内存地
址获得的,这样就会导致,即使该对象已经存在HashSet中,但是因为hashCode不同,还会再次被存
入。
因此要重写hashCode保证:如果equals判断是相等的,那hashCode值也要相等。

3. 什么是拆箱和装箱?

我理解的就是基本类型和包装类型的相互转换:
装箱就是基本数据类型可以直接赋值给包装类型,也就是Object变量
拆箱就是包装类型也可以自动转化为基本数据类型进行赋值或者比较

4. final类有什么特点?

  1. 不可以被继承
  2. final修饰的方法不可被重写
  3. final修饰的变量:基本数据类型值不可修改,引用数据类型指向不可发生变化

5.谈谈final、finally和finalize的区别

final是修饰成员变量、类、方法,表示不可再改变
finally是处理异常的关键字,表示最后执行
finalize是Object类的一个方法,在垃圾收集器执行的时候会执行被回收对象的这个方法,可以覆
盖此方法提供垃圾收集时的其他资源回收,例如文件关闭 等等。

6.垃圾回收

  1. GC是什么?为什么要有GC?
    GC时垃圾收集的意思,Gabage Collection。内存处理是开发人员容易出现问题的地方,忘记或者错误
    地内存回收会导致程序或者系统的不稳定甚至崩溃,Java提供的垃圾回收机制可以自动检测对象是否超
    过作用域从而达到自动回收的目的。
  2. 垃圾回收机制
    Java垃圾回收机制:不需要显示的去释放一个对象的内存,而是由JVM自动机型管理。在Jvm中有一个
    低优先级的垃圾回收线程。在正常情况下是不会执行的,只有在虚拟机空闲时,或者堆内存不足时会触
    发执行,扫描那些没有被任何引用的对象,将它们添加到要回收的集合中,然后进行回收操作。
  3. 如何判断一个对象是否存活?GC对象的判断方法?
    1、 引用计数法:给每一个对象都设置一个引用计数器,当有一个地方引用这个对象时,则
    count+=1,引用失效时,count-=1,当count=0时,说明此对象没有被其他对象引用,也就是死
    对象。将会被GC回收。
    简单,但会出现循环引用,即: A引用B,B引用A。
    2、可达性分析:GC_roots作为对象的起始点,从这些节点开始向下搜索,走过的路径称为引用链,
    当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象不可用的
    在这里插入图片描述

上图中,Object1~Object4都可以被GC Root访问到,而Object5~Object7都不可以被访问到,这也就是说。也就是说,Object5、6、7这三个对象就是不可达的,下次垃圾回收的时候,可能就会被回收掉。
其实并不是所有的对象都可以作为GC Roots的对象,只有下列的对象可以作为GC Roots的对象。

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
  • 本地方法栈中JNI(即一般说的Native方法)引用的对象

既然是引用计数法,那肯定就有各种引用,下面来说说一些引用。

  • 引用:指在程序代码之中普遍存在的,类似 Object obj = new Object() 这类的引用,只要强 引用还存在,垃圾收集器永远不会回收被引用的对象
  • 软引用:用来描述一些还有用但并非必需的对象。对于软引用关联着的对象,在系统将要发生内存 溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收。如果这次回收还没有足够的内存,才会抛出内存溢出异常。在JDK1.2之后,提供了SoftReference类来实现软引用
  • 弱引用:用来描述非必需对象,但是他的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。在JDK1.2之后,提供了WeakReference类来实现弱引用
  • 虚引用:也被称为幽灵引用或者幻影引用。它是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。在JDK1.2之后,提供了PhantomReference类来实现虚引用。供对象被finalize之后,执行指定的逻辑的机制(cleaner)

7. 关键字native

一个Native Method就是一个java调用非java代码的接口。这个接口写在java中,实现方式是用其他语
言,eg: C或C++
native不可与abstract一起使用,可以重写。
可以将native方法比作Java程序同C程序的接口,其实现步骤:

  • 1、在Java中声明native()方法,然后编译;
    1. 用javah产生一个.h文件;
    1. 写一个.cpp文件实现native导出方法,其中需要包含第二步产生的.h文件(注意其中又包含了JDK 带的jni.h文件);
    1. 将第三步的.cpp文件编译成动态链接库文件
    1. 在Java中用System.loadLibrary()方法加载第四步产生的动态链接库文件,这个native()方法就可以 在Java中被访问了

6、集合

  • Set如何区分重复与否?
    使用equals,而不是==
  • 当向集合Set中增加对象时,首先集合计算要增加对象的hashCode码,根据该值来得到 一个位置用来存放当前对象。 如果在该位置没有一个对象存在的话,那么集合Set认为该对象在集合中不存在,直接 增加进去。 如果在该位置有一个对象存在的话,接着将准备增加到集合中的对象与该位置上的对象 进行equals方法比较。 如果该equals方法返回false,那么集合认为集合中不存在该对象,再进行一次散列, 将该对象放到散列后计算出来的地址中。 如果equals方法返回true,那么集合认为集合中已经存在该对象了,不再将该对象增加到集合中。
  • 重写equals方法的时候必须重写hashCode方法。如果一个类的两个对象,使用equals 方法比较时,结果为true,那么这两个对象具有相同的hashCode。原因是equals方法为true,表明是同一个对象,它们hashCode当然相同。(Object类的equals方法比较的是地址)
  • Object类的hashCode方法返回的是Object对象的内存地址。我们可以通
    Integer.toHexString(newObject().hashCode());来得到。
  • Java里面的HashSet中,如何判断两个对象是否相等?
    先hashcode,如果相等则用equals,因为hashcode快。
  • 判断两个对象的hashCode是否相等。 如果不相等,认为两个对象不相等。完毕 如果相等,转入2
  • 判断两个对象是否equals 如果不相等,认为两个对象不相等。 如果相等,认为两个对象相等。
  • 数组和集合的区别?
    数组存放基本数据类型和对象引用,集合类存放对象的引用。
    数组长度无法动态改变,集合可以
    数组无法判断实际大小,只有长度,集合有.size()方法
    集合以类的方式存在,具有封装继承多态的特性。
    ★ 4. Java集合类框架的基本接口有哪些?
    Collection和Map(两个接口),元素集合和键值对集合。
    List和Set接口继承Collection接口,
    HashMap和HashTable实现了Map接口,HashTable线程安全。
    上述类图中,实线边框的是实现类,比如ArrayList,LinkedList,HashMap等,折线边框的是抽象
    类,比如AbstractCollection,AbstractList,AbstractMap等,而点线边框的是接口,比如
    Collection,Iterator,List等。
  • 说说 List,Set,Map 三者的区别?
    List (对付顺序的好帮⼿): 存储的元素是有序的、可重复的。
    Set (注重独⼀⽆⼆的性质): 存储的元素是无序的、不可重复的。
    Map (⽤ Key 来搜索的专家): 使⽤键值对(kye-value)存储,类似于数学上的函数 y=f(x),“x”代
    表 key,"y"代表 value,Key 是⽆序的、不可重复的,value 是⽆序的、可重复的,每个键最多映
    射到⼀个值。
  • 什么是迭代器?
    Iterator是一种遍历集合类元素的对象,提供了一种通用的访问集合元素的方法,无需知道集合内部的
    结构和实现细节。迭代器以内部类的形式存在每个集合类中。无法逆向访问元素, 在使用迭代器遍历集
    合时,不能在集合中添加或删除元素
    常用方法:
    hasNext() :判断是否还有下一个元素。
    next() :返回下一个元素,并将迭代器的位置向后移动。
    remove() :从集合中删除迭代器返回的最后一个元素。
    使用迭代器访问ArrayList:
    import java.util.;
    public class Test{
    public static void main(String[] args) {
    List list=new ArrayList();
    list.add(“Hello”);
    list.add(“World”);
    list.add(“HAHAHAHA”);
    //第一种遍历方法使用foreach遍历List
    for (String str : list) { //也可以改写for(int
    i=0;i<list.size();i++)这种形式
    System.out.println(str);
    }
    //第二种遍历,把链表变为数组相关的内容进行遍历
    String[] strArray=new String[list.size()];
    list.toArray(strArray);
    for(int i=0;i<strArray.length;i++) //这里也可以改写为 foreach(String
    str:strArray)这种形式
    {
    System.out.println(strArray[i]);
    }
    //第三种遍历 使用迭代器进行相关遍历
    Iterator ite=list.iterator();
    while(ite.hasNext())//判断下一个元素之后有值
    {
    System.out.println(ite.next());
    }
    }
    }
    遍历Map
    import java.util.
    ;
    public class Test{
    public static void main(String[] args) {
    Map<String, String> map = new HashMap<String, String>();
    map.put(“1”, “value1”);
    map.put(“2”, “value2”);
    map.put(“3”, “value3”);
    //第一种:普遍使用,二次取值
    System.out.println(“通过Map.keySet遍历key和value:”);
    for (String key : map.keySet()) {
    System.out.println("key= "+ key + " and value= " + map.get(key));
    }
    //第二种
    System.out.println(“通过Map.entrySet使用iterator遍历key和value:”);
    Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
    while (it.hasNext()) {
    Map.Entry<String, String> entry = it.next();
  • Iterator和ListIterator的区别?
    Iterator 和 ListIterator 是Java中两种不同的迭代器实现,它们都用于遍历集合元素,但在功能上
    有一些区别。
  • Iterator 能用于遍历List、Set、Map等集合类的元素,而 ListIterator 只能用于遍历List集合
    的元素。因此,如果要遍历Set或Map等集合,只能使用 Iterator ,而不能使用
    ListIterator 。
  • Iterator 只支持向前遍历集合元素,而 ListIterator 支持向前和向后遍历集合元素,可以使用
    previous() 方法获取前一个元素。因此,如果需要对List集合进行双向遍历,可以使用
    ListIterator ,而不能使用 Iterator 。
  • ListIterator 相对于 Iterator 增加了一些额外的方法,如 add() 、 set() 、
    hasPrevious() 、 previousIndex() 、 nextIndex() 等,可以在遍历过程中对集合元素进行插
    入、修改、删除等操作。而 Iterator 只有 remove() 方法,只能用于删除集合元素,不能进行插
    入、修改等操作。
    System.out.println("key= " + entry.getKey() + " and value= " +
    entry.getValue());
    }
    //第三种:推荐,尤其是容量大时
    System.out.println(“通过Map.entrySet遍历key和value”);
    for (Map.Entry<String, String> entry : map.entrySet()) {
    System.out.println("key= " + entry.getKey() + " and value= " +
    entry.getValue());
    }
    //第四种
    System.out.println(“通过Map.values()遍历所有的value,但不能遍历key”);
    for (String v : map.values()) {
    System.out.println("value= " + v);
    }
    }
    }
    import java.util.ArrayList;
    import java.util.ListIterator;
    public class Main {
    public static void main(String[] args) {
    ArrayList list = new ArrayList<>();
    list.add(“Java”);
    list.add(“Python”);
    list.add(“C++”);
    // 使用ListIterator遍历List集合
    ListIterator iterator = list.listIterator();
    while (iterator.hasNext()) {
    String item = iterator.next();
    System.out.println(item);
    // 对集合元素进行修改和插入操作
    if (item.equals(“Java”)) {
    iterator.set(“Java SE”);
  • Java中的HashMap的工作原理?
    实现了Map接口,以键值对的形式存储数据。
    HashMap需要哈希函数对key计算hash值,使用对象的hashcode和equals方法来进行存取。
    不可有重复的键,重复的充要条件是equals返回true。
    11.HashMap实现方式
    数组+链表+红黑树
    当链表长度大于 8 时,我们会对链表进行“树化”操作,将其转换成一颗红黑树(一种二叉树,左边节点
    的值小于根节点,右边节点的值大于根节点)
    HashMap:上面也说了,HashMap 的底层实现是数组+链表+红黑树的形式的,同时它的数组的默认初
    始容量是16、扩容因子为0.75,每次采用2 倍的扩容。 也就是说,每当我们数组中的存储容量达到75%
    的时候,就需要对数组容量进行2 倍的扩容。
    iterator.add(“Java ME”);
    }
    }
    // 再次使用ListIterator遍历List集合
    System.out.println(“修改后的List集合:”);
    iterator = list.listIterator();
    while (iterator.hasNext()) {
    String item = iterator.next();
    System.out.println(item);
    }
    }
    }
    Java
    Python
    C++
    修改后的List集合:
    Java SE
    Java ME
    Python
    C++
  • error 和 exception的区别
    这两个我理解的是错误和异常,都是Throwable的子类,Error更加严重
    Exception是程序正常运行中,可以预料到的意外情况,可以捕获,进行相应处理。
    可检测异常:编译检查的部分,要不然编译不通过
    不可检测异常:eg:
    Error在正常运行中,不太可能出现的情况。绝大部分的Error 都会导致程序处于非正常的,不可恢
    复的状态, 不需要捕获, 常见的OutOfMemoryError 是Error的子类.
  • abstract的method是否可同时是static,是否可同时
    是native,否可同时是synchronized
  • 不可是static,之类需要被实现,static和子类没有关系
  • 不可是native,native方法表示该方法需要用另一种依赖平台的编程语言实现,不存在子类被实现
    问题。
  • synchronized 是同步,然而同步是需要有具体操作才能同步的,如果像abstract只有方法声明,
    那同步一些什么东西就会成为一个问题了,当然抽象方法在被子类继承以后,可以添加同步。
  • 接口是否可继承接口?抽象类是否可实现接口?抽象类
    是否可继承实现类?
    我认为
    接口可以继承接口
    抽象类可以实现接口
    抽象类可以继承实现类,但前提是实现类必须有明确的构造函数。
    12.try中的return,finally会不会执行?return前还是
    return后?
    会执行,会在return 前执行。
    The finally block always executes when the try block exits.`
    当尝试块退出时,最终块总是执行。
  • try中有return, 会先将值暂存,无论finally语句中对该值做什么处理,最终返回的都是try语句中的
    暂存值。
  • 当try与finally语句中均有return语句,会忽略try中return。
    package top.yanzx;
    /**
  • @Author: yanzx
  • @Date: 2023/2/27 14:26
  • @Description:
  • int 和 Integer有什么区别?
    int是基本数据类型,integer是引用数据类型,是int的包装类。八大基本类型都有相应的包装类。
  • 描述一个JVM加载class文件的原理机制、
    简答: JVM中类的加载是由classloader和它的子类来实现的, java classloader是一个重要的java运行系
    统组件,它负责查找和装入类文件的类。
    JVM(Java Virtual Machine)是一个运行Java程序的虚拟机,它负责将Java程序的字节码文件加载到内
    存中,并执行这些字节码指令。下面是JVM加载class文件的基本原理机制:
  • 类加载器:JVM中的类加载器(ClassLoader)负责加载Java类文件到内存中。ClassLoader可以从
    文件系统、网络或其他来源中加载class文件。
  • 类加载过程:当JVM需要一个类时,它会先请求ClassLoader将类加载到内存中。ClassLoader会
    根据类的全限定名(Fully Qualified Name)查找相应的class文件,如果找到则加载这个class文
    件,否则抛出ClassNotFoundException异常。
  • 类加载阶段:类加载器加载class文件时,会经历以下3个阶段:
    (1) Loading(加载)阶段:在这个阶段,类加载器将class文件中的二进制数据读入到内存中,并
    创建一个对应的Class对象。
    (2) Linking(连接)阶段:在这个阶段,类加载器会执行以下操作:
    */
    public class Demo04Try {
    public static void main(String[] args) {
    System.out.println(func1());
    }
    public static int func1(){
    int x = 1;
    try {
    // 返回的暂存值,return会暂存x的值,finally也会执行,但修改的值和返回的值无
    关。
    return x;
    }finally {
    x +=1 ;
    System.out.println(x);
    }
    }
    }
    a. 验证:验证class文件的正确性,包括字节码格式、符号引用等方面的验证。
    b. 准备:为类的静态变量分配内存,并初始化为默认值。
    c. 解析:将类中的符号引用转化为直接引用,即将类、方法、变量等符号解析为内存地址。
    (3) Initialization(初始化)阶段:在这个阶段,类的静态变量和静态代码块会被执行,完成类的
    初始化。
  • 类加载器的层次结构:JVM中的类加载器形成了一个层次结构,ClassLoader可以有多个,每个
    ClassLoader都有自己的父ClassLoader。当一个类需要被加载时,JVM会先从最上层的
    ClassLoader开始查找,如果找不到则向下逐级查找,直到找到为止。
  • 类的生命周期:类的生命周期包括加载、验证、准备、解析、初始化、使用和卸载等阶段。JVM中
    的类加载器和类的生命周期是密切相关的,ClassLoader负责加载、验证、准备、解析和卸载
    类,而类的初始化和使用则由JVM负责。
  • 封装具有的特性
    封装的作用是对象外部不能随意存取对象的内部数据,避免外部错误。只提供少量接口对内部成员变量
    进行操作,因此大大减少了内部的修改对外部的影响。
    特性:
    数据吟唱
    接口访问
    实现隔离
    可维护性
    重用性
    封装(Encapsulation)是面向对象编程中的一种重要概念,它指的是将数据和方法包装在一个类中,
    隐藏实现细节,仅向外界提供有限的访问接口,从而实现数据的安全性、可靠性和易用性。封装具有以
    下特性:
  • 数据隐藏:封装将类的数据和方法封装在一起,对外部世界屏蔽了内部的实现细节,只提供有限的
    访问接口。这样可以保证数据的安全性,防止外部恶意修改数据,同时也保护了数据的完整性和一
    致性。
  • 接口访问:封装通过接口访问类的内部数据和方法,提供了一种良好的数据交互方式。外部世界只
    能通过类的接口来访问内部数据和方法,这种限制了外部世界对类的干扰,使得类的实现更加稳定
    和可靠。
  • 实现隔离:封装使得类的实现细节被隐藏在类的内部,外部世界无法访问类的实现细节。这样可以
    使得类的实现更加自由,可以在不影响外部世界的情况下自由修改和升级类的实现。
  • 可维护性:封装提高了类的可维护性,由于封装使得类的实现细节被隐藏起来,类的内部实现可以
    自由修改,而不会影响外部世界对类的使用。这样可以使得类的维护更加方便和安全。
  • 重用性:封装提高了类的重用性,由于类的内部实现被隐藏起来,外部世界只能通过类的接口来访
    问内部数据和方法。这样可以使得类的接口更加通用和稳定,从而提高了类的重用性。
  • 什么时候应用带参构造函数?
  • 需要对对象进行一次性初始化时
  • 父类拥有带参构造函数,子类继承父类,也需要带参构造函数,并调用父类构造函数。
  • 方法重载和重写的区别
    重载(OverLoading)是多个重名函数,具有不同的参数数据类型或参数个数。是一个类中多态性的
    一种体现。但不能以返回类型作为重载函数的区分标准。两个同名函数具有相同的参数类型,但是访问
    权限不同或者返回类型不同是不可能的。
    重写(Overriding)是子类继承父类,重写父类的方法,函数名参数和返回类型都要一样。子类所重
    写方法的访问权限不能小于父类的。
  • 接口隔离原则和单一原则如何理解?
    强调了代码的模块化、灵活性和可维护性
    单一是指接口要尽量的智能单一,不能为了实现一个接口而被迫实现不需要的方法情况。隔离的是实现
    和调用,这样才能真正解决团队的并行开发问题。
    避免降低接口的灵活性和可用性。
  • 不适用异常处理程序会出现什么问题?
  • 虚拟机会打印异常信息。
  • 程序终止运行
    要把异常尽早处理,这样产生的影响范围越小。因此,不要把自己能处理的异常抛给调用者。
  • finally在什么时候使用?
    finally是在任何情况下都会执行的部分。可以在:
  • 查询数据库发生异常时,关闭数据库连接。
  • 文件读取时,关闭文件等等。
  • 不要在里边放return,无论怎样都会返回这个值,没有意义。
  • throw和throws的区别?
    throw用来抛出异常,在方法体内。
    throws用来声明方法可能会抛出什么异常,在函数声明之后。
    简而言之,throw关键字用于抛出一个异常对象,throws关键字用于声明方法可能会抛出的异常类型。
  • String和StringBuffer、StringBuilder的区别
  • string和stringbuffer、stringbuiler都可一存储操作字符串
  • String时不可以修改的,后两者可以修改
  • stringbuffer线程安全,stringbuiler不安全,String则是非线程安全的
  • 性能:由于String是不可变的,每次对String进行修改都会创建一个新的对象,这会产生大量的垃
    圾对象,导致程序运行效率低下。而StringBuffer则是可变的,不需要每次都创建新的对象,因此
    在处理大量字符串时,使用StringBuffer的效率要比String高。
  • 多线程
  • java中有几种方法可以实现线程
    两种方法:
  • 继承Thread类,重写run()方法,创建Thread对象,调用start()方法启动线程。
  • 实现Runnable接口:实现run()方法,创建thread对象实现了runnable接口的对象传进去,最后调
    用start()方法。
  • 使用线程池,避免频繁的创建和销毁线程
  • 用什么关键修饰同步方法?
    synchronized 关键字。 synchronized 修饰的方法称为同步方法,它保证在任意时刻只有一个线程可
    以执行该方法,从而避免了多线程访问共享资源时出现的数据竞争和不一致性问题。
    可以放在方法的生命出,也可以放在方法的内部块中。
    在方法声明处使用 synchronized 关键字时,它会将整个方法体都变为同步代码块,即只有一个线
    程可以进入方法体内执行代码。
    在方法内部块上使用 synchronized 关键字时,它会将该代码块变为同步代码块,即只有一个线程
    可以执行该代码块内的代码。
    // 继承Thread类创建线程
    public class MyThread extends Thread {
    public void run() {
    System.out.println(“线程启动了”);
    }
    public static void main(String[] args) {
    MyThread myThread = new MyThread();
    myThread.start();
    }
    }
    // 实现Runnable接口创建线程
    public class MyRunnable implements Runnable {
    public void run() {
    System.out.println(“线程启动了”);
    }
    public static void main(String[] args) {
    MyRunnable myRunnable = new MyRunnable();
    Thread thread = new Thread(myRunnable);
    thread.start();
    }
    }
    public class MyCounter {
  • 为什么不推荐使用stop()和suspend()方法
    stop() 方法会强制终止一个线程,可能导致一些数据不一致或资源未释放的问题,可能会破坏程
    序的稳定性和完整性。因此,推荐使用 interrupt() 方法来终止线程的执行,因为 interrupt()
    方法会给线程一个中断信号,让线程自行判断是否终止执行,并且可以在执行过程中清理资源和状
    态。
    suspend() 方法会暂停线程的执行,但不会释放线程占用的锁,这可能会导致死锁的发生。因
    此,推荐使用 wait() 和 notify() 方法来实现线程之间的协作和通信。
  • sleep()和wait()的区别
    sleep()是线程类Thread的static方法,不释放锁。但会让出CPU执行时间分片。锁不释放不影响这
    个过程,如果其他线程都需要这个没有释放的锁,那最终结果就是让出执行权,大家都不执行。
    wait()是Object类的方法,释放锁,暂停线程。直到其他线程调用了该对象的 notify() 或
    notifyAll() 方法,或者等待的时间到了。 wait() 方法主要用于多线程之间的协作和通信,如
    线程间的同步、通知和等待等。
    sleep() 方法可以在任意时刻使用,而 wait() 方法必须在 synchronized 块或方法中使用,否则
    会抛出 IllegalMonitorStateException 异常。
    如果是控制线程的执行速度和时序,可以使用 sleep() 方法;如果是实现线程间的协作和通信,
    可以使用 wait() 方法。同时,使用 wait() 方法时需要注意线程安全和死锁等问题。
  • 线程同步概念
    private int count;
    // 同步方法
    public synchronized void increment() {
    count++;
    }
    public int getCount() {
    return count;
    }
    public static void main(String[] args) {
    MyCounter counter = new MyCounter();
    for (int i = 0; i < 1000; i++) {
    new Thread(() -> {
    counter.increment();
    }).start();
    }
    System.out.println(counter.getCount()); // 1000
    }
    }
    package top.yanzx;
    import com.sun.org.apache.bcel.internal.generic.NEW;
    import java.lang.management.ThreadInfo;
    /**
  • @Author: yanzx
  • @Date: 2023/2/27 17:12
  • @Description:
    • // Java 8之前:
  • new Thread(new Runnable() {
  • @Override
  • public void run() {
  • System.out.println(“Before Java8”);
  • }
  • }).start();
      • new Thread( () -> System.out.println(“In Java8, Lambda expression”)
        ).start();
    1. 创建任何类型的对象,作为监视器
    1. 使用 synchronized()代码块或者方法
    1. done
      • */
        public class Demo06ThreadSeller {
        public static int tickets = 100;
        public static void main(String[] args) {
        // lambda相当于实现了runnable的run方法
        Object obj = new Object(); // 对象锁
        Runnable seller = () -> {
        while (true){
        // 加锁
        synchronized(Demo06TheadCounter.class){ // 类锁,类的字节码
        // synchronized(obj){ // monitor enter 加锁
  • 同步和异步的不同,使用时间?
    多线程之间、共享数据需要存取修改等操作,需要进行同步处理。
    当程序执行了一个耗时较长的操作,并且需要及时返回,那么就需要使用异步,先返回结果。
  • 在Monitor内部是如何做线程同步的?
    监视器和锁咋Java虚拟机中是一块使用的。监视器监视一块同步代码块,确保每一次只有一个线程执行
    同步代码块。每个监视器都和一个对象引用相关联。线程在获取锁之前不能执行临界区代码。
  • 锁和监视器二者区别?
    监视器是一种同步模型,和java语言没有关系,其他语言也可以使用监视器来进行同步代码块的访问,
    java语言是通过synchronized(应该就是你说的锁)关键字来声明同步块的,具体是怎么同步的,是使
    用的监视器模型来同步的。
    锁为实现监视器提供必要的支持。
    Java中锁和监视器有以下区别:1.基本概念不同;2.主要作用不同;3.执行机制不同。 基本概念不同在
    于,锁是对象内存堆中头部的一部分数据,任何程序都可以使用它来协调对对象的多线程访问;而监视
    器是一种同步结构,它允许线程同时互斥(使用锁)和协作。
  • Java中,什么是构造函数?什么是的构造函数重载?什
    么是复制构造函数?
    构造函数:创建对象时需要调用的函数。用于初始化对象的成员变量。默认会有无参构造函数。
    构造函数重载:根据参数列表不同,具有多个构造函数。
    // 临界区: 访问临界资源的那段代码 需要具有原子性
    // 加锁,被锁定的区域只有一个去执行,synchronized关键字
    try {
    if (tickets <= 0)
    break;
    Thread.sleep(10); // 不会释放锁,所以会阻塞其他线程
    System.out.println(Thread.currentThread().getName() +
    “正在售卖第” + tickets-- + “张票”);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }// monitor exit 释放锁
    }
    };
    new Thread(seller, “窗口1”).start();
    new Thread(seller, “窗口2”).start();
    new Thread(seller, “窗口3”).start();
    new Thread(seller, “窗口4”).start();
    }
    }
    复制(拷贝)构造函数:Java不支持C++那样的复制构造函数,这个不同点时因为java返回的是引
    用类型。
  • Java支持多继承吗?
    不支持,一个类只能继承一个父类,但是可以实现多个接口。
  • 谈谈你所理解的MVC
    M:model,模型,通常包含业务逻辑和数据访问逻辑,负责数据的增删改查等操作
    V:view,视图层,处理页面展示。
    C:controller,负责处理用户的交互事件。
    降低了代码的耦合度。实现了代码的分层和模块化,使得开发过程更加可控和可维护。通过MVC模式,
    可以将不同的职责分配到不同的模块中,使得整个应用程序更加灵活和可扩展。例如,可以在不改变模
    型和视图的前提下,只通过更改控制器来实现新的业务需求。
    比如:SpringMVC、Django、gin+gorm

相关文章:

【研究生复试】计算机软件工程人工智能研究生复试——资料整理(速记版)——JAVA

1、JAVA 2、计算机网络 3、计算机体系结构 4、数据库 5、计算机租场原理 6、软件工程 7、大数据 8、英文 自我介绍 1. Java 1. 和 equals的区别 比较基本数据类型是比较的值&#xff0c;引用数据类型是比较两个是不是同一个对象&#xff0c;也就是引用是否指向同 一个对象&…...

JVM-JVM中对象的生命周期

申明&#xff1a;文章内容是本人学习极客时间课程所写&#xff0c;文字和图片基本来源于课程资料&#xff0c;在某些地方会插入一点自己的理解&#xff0c;未用于商业用途&#xff0c;侵删。 原资料地址&#xff1a;课程资料 对象的创建 常量池检查:检查new指令是否能在常量池…...

RegExp正则表达式左限定右限定左右限定,预查询,预查寻,断言 : (?<= , (?= , (?<! , (?!

RegExp正则表达式左限定右限定左右限定,预查询,预查寻,断言 : (?< , (? , (?<! , (?! 有好多种称呼 (?< , (? , (?<! , (?! 有好多种称呼 , 我称为: 左限定, 右限定, 左否定, 右否定 (?<左限定)    (?右限定)(?<!左否定)    (?!右限定) 再…...

相机图像质量研究(30)常见问题总结:图像处理对成像的影响--重影

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…...

问题记录——c++ sort 函数 和 严格弱序比较

引出 看下面这段cmp函数的定义 //按照vector第一个元素升序排序 static bool cmp(const vector<int>& a, const vector<int>& b){return a[0] < b[0]; }int eraseOverlapIntervals(vector<vector<int>>& intervals) {//按区间左端排序…...

《Go 简易速速上手小册》第9章:数据库交互(2024 最新版)

文章目录 9.1 连接数据库 - Go 语言的海底宝藏之门9.1.1 基础知识讲解安装数据库驱动数据库连接 9.1.2 重点案例&#xff1a;用户信息管理系统准备数据库Go 代码实现连接数据库添加新用户查询用户信息用户登录验证主函数 9.1.3 拓展案例 1&#xff1a;批量添加用户准备数据库Go…...

redis的hash数据结构底层简记

hash&#xff1a;k和v都是string的hash表。 HSET&#xff08;设置集合数据&#xff0c;4.0之前只能设置1个&#xff0c;之后可以设置多个&#xff09;&#xff0c;HSETNX(若k不存在则设置对应v)&#xff0c;HDEL&#xff08;删除指定kv&#xff0c;可以一次删除多个&#xff09…...

清除Django的管理员admin站点中“Recent Actions“最近活动面板上的所有信息

清除Django的管理员admin站点中"Recent Actions"最近活动面板上的所有信息 本文主要介绍了如何清除Django的管理员admin站点中"Recent Actions"最近活动面板上的所有信息 操作步骤如下 进入Django项目目录中运行代python manage.py shell进入Django shell…...

【JVM篇】ThreadLocal中为什么要使用弱引用

文章目录 &#x1f354;ThreadLocal中为什么要使用弱引用⭐总结 &#x1f354;ThreadLocal中为什么要使用弱引用 ThreadLocal可以在线程中存放线程的本地变量&#xff0c;保证数据的线程安全 ThreadLocal是这样子保存对象的&#xff1a; 在每个线程中&#xff0c;存放了一个…...

Stable Diffusion教程——stable diffusion基础原理详解与安装秋叶整合包进行出图测试

前言 在2022年&#xff0c;人工智能创作内容&#xff08;AIGC&#xff09;成为了AI领域的热门话题之一。在ChatGPT问世之前&#xff0c;AI绘画以其独特的创意和便捷的创作工具迅速走红&#xff0c;引起了广泛关注。随着一系列以Stable Diffusion、Midjourney、NovelAI等为代表…...

【JavaEE】_线程与多线程的创建

目录 1. 线程的概念 2. 创建与使用多线程 2.1 方式1&#xff1a;继承Thread类 2.2 方式2&#xff1a; 实现Runnable接口 2.3 以上两种创建线程方式的对比 3. 多线程的优势-增加运行速度 1. 线程的概念 进程的存在是由于系统的多任务执行需求&#xff0c;这也要求程序员进…...

【前端工程化面试题】如何优化提高 webpack 的构建速度

使用最新版本的 Webpack 和相关插件: 每个新版本的 Webpack 都会带来性能方面的改进和优化&#xff0c;因此始终确保你在使用最新版本。同时&#xff0c;更新你的相关插件也是同样重要的。 使用DllPlugin动态链接库: 使用DllPlugin和DllReferencePlugin来将第三方库的代码进行…...

免费chatgpt使用

基本功能如下&#xff1a; https://go.aigcplus.cc/auth/register?inviteCode3HCULH2UD...

OpenCV识别人脸案例实战

使用级联函数 基本流程 函数介绍 在OpenCV中&#xff0c;人脸检测使用的是cv2.CascadeClassifier.detectMultiScale()函数&#xff0c;它可以检测出图片中所有的人脸。该函数由分类器对象调用&#xff0c;其语法格式为&#xff1a; objects cv2.CascadeClassifier.detectMul…...

VOSK——离线语音库

文章目录 识别函数调用添加自定义热词表1. SetWords2. SetLatticeWords3. SetPartialWords使用示例注意1. SetMaxAlternatives2. SetNLSML3. SetSpkModel4. SetGrammar使用示例注意SetLogLevel示例用法注意事项 识别函数调用 在使用Vosk库进行语音识别时&#xff0c;PartialRe…...

ELAdmin 隐藏添加编辑按钮

使用场景 做了一个监控模块&#xff0c;数据都是定时生成的&#xff0c;所以不需要手动添加和编辑功能。 顶部不显示 可以使用 true 或者 false 控制现实隐藏 created() {this.crud.optShow {add: false,edit: false,del: true,download: true,reset: true}},如果没有 crea…...

浅谈Websocket

由于 http 存在⼀个明显的弊端(消息只能有客户端推送到服务器端,⽽服务器端不能主动推送到客户端),导致如果服务器如果有连续的变化,这时只能使⽤轮询,⽽轮询效率过低,并不适合。于是 WebSocket 被发明出来 WebSocket 是⼀种在 Web 应⽤程序中实现双向通信的协议。与传…...

JavaScript闭包详细介绍

文章目录 什么是闭包优点&#xff1a;变量持久化&#xff1a;封装私有变量&#xff1a;模块化&#xff1a;函数工厂&#xff1a; 缺点&#xff1a;内存占用&#xff1a;调试困难&#xff1a;过度使用导致性能下降&#xff1a; 什么是闭包 闭包是指有权访问另一个函数作用域中的…...

pytorch神经网络入门代码

import torch import torch.nn as nn import torch.optim as optim import torchvision import torchvision.transforms as transforms# 定义神经网络结构 class SimpleNN(nn.Module):def __init__(self, input_size, hidden_size, num_classes):super(SimpleNN, self).__init_…...

代码随想录算法训练营第三十四天|860.柠檬水找零 406.根据身高重建队列 452. 用最少数量的箭引爆气球

860.柠檬水找零 链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 细节&#xff1a; 1. 首先根据题意就是只有5.的成本&#xff0c;然后就开始找钱&#xff0c;找钱也是10.和5. 2. 直接根据10 和 5 进行变量定义&#xff0c;然后去循环…...

Ditto:提升剪贴板体验的宝藏软件(复制粘贴效率翻倍、文本处理好助手)

名人说&#xff1a;莫道桑榆晚&#xff0c;为霞尚满天。——刘禹锡&#xff08;刘梦得&#xff0c;诗豪&#xff09; 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、什么是Ditto&#xff1f;二、下载安装三、如…...

【自然语言处理-工具篇】spaCy<2>--模型的使用

前言 之前已经介绍了spaCy的安装,接下来我们要通过下载和加载模型去开始使用spaCy。 下载模型 经过训练的 spaCy 管道可以作为 Python 包安装。这意味着它们是应用程序的一个组件,就像任何其他模块一样。可以使用 spaCy download的命令安装模型,也可以通过将 pip 指向路径或…...

Java之通过Jsch库连接Linux实现文件传输

Java之通过JSch库连接Linux实现文件传输 文章目录 Java之通过JSch库连接Linux实现文件传输1. JSch2. Java通过Jsch连接Linux1. poxm.xml2. 工具类3. 调用案例 1. JSch 官网&#xff1a;JSch - Java Secure Channel (jcraft.com) JSch是SSH2的纯Java实现。 JSch 允许您连接到 ss…...

Nginx七层负载均衡之动静分离

思路: servera:负载均衡服务器 serverb:静态服务器 serverc:动态服务器 serverd:默认服务器 servera(192.168.233.132): # 安装 Nginx 服务器 yum install nginx -y#关闭防火墙和selinux systemctl stop firewalld setenforce 0# 切换到 Nginx 配置文…...

305_C++_定义了一个定时器池 TimerPool 类和相关的枚举类型和结构体

头文件:定义了一个定时器池 TimerPool 类和相关的枚举类型和结构体 #ifndef TIMERPOOL_H #define TIMERPOOL_H #include "rsglobal.h" #include "taskqueue.h" #incl...

大整数因数分解工具——yafu

一、安装 yafu--下载链接 二、配置环境变量&#xff0c;直接从cmd打开 1.找到yafu-x64.exe 所在的文件路径 2.点击设置——系统——系统信息——高级系统设置——环境变量——点击PATH&#xff08;上下都可以&#xff09;——新建 添加yafu-x64.exe 所在路径——点击确定 3…...

非关系型数据库(NOSQL)和关系型数据库(SQL)区别详解

前言&#xff1a; 在我们的日常开发中&#xff0c;关系型数据库和非关系型数据库的使用已经是一个成熟的软件产品开发过程中必不可却的存储数据的工具了。那么用了这么久的关系数据库和非关系型数据库你们都知道他们之间的区别了吗&#xff1f;下面我们来详细的介绍一下。 关系…...

7.Cloud-GateWay

0.概述 https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/ 1.入门配置 1.1 POM <!--新增gateway--> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-sta…...

【Linux】Framebuffer 应用

# 前置知识 LCD 操作原理 在 Linux 系统中通过 Framebuffer 驱动程序来控制 LCD。 Frame 是帧的意思&#xff0c; buffer 是缓冲的意思&#xff0c;这意味着 Framebuffer 就是一块内存&#xff0c;里面保存着一帧图像。 Framebuffer 中保存着一帧图像的每一个像素颜色值&…...

markdown绘制流程图相关代码片段记录

有时候会使用typora来绘制一些流程图&#xff0c;进行编码之类的工作&#xff0c;在网络搜集了一些笔记&#xff0c;做个记录&#xff0c;方便日后进行复习&#xff0c;相关的记录如下&#xff1a; 每次作图时&#xff0c;代码以「graph <布局方向>」开头&#xff0c;如…...

云计算基础-计算虚拟化-CPU虚拟化

CPU指令系统 在CPU的工作原理中&#xff0c;CPU有不同的指令集&#xff0c;如下图&#xff0c;CPU有4各指令集&#xff1a;Ring0-3&#xff0c;指令集是在服务器上运行的所有命令&#xff0c;最终都会在CPU上执行&#xff0c;但是CPU并不是说所有的命令都是一视同仁的&#xf…...

MySQL数据库⑪_C/C++连接MySQL_发送请求

目录 1. 下载库文件 2. 使用库 3. 链接MySQL函数 4. C/C链接示例 5. 发送SQL请求 6. 获取查询结果 本篇完。 1. 下载库文件 要使用C/C连接MySQL&#xff0c;需要使用MySQL官网提供的库。 进入MySQL官网选择适合自己平台的mysql connect库&#xff0c;然后点击下载就行…...

选择排序和快速排序(1)

目录 选择排序 基本思想 选择排序的实现 图片实现 代码实现 快速排序 基本思想 快速排序的实现 图片实现 代码实现 选择排序 基本思想 每一次从待排序的数据元素中选出最小&#xff08;最大&#xff09;的元素&#xff0c;存放在序列的起始位置&#xff0c;直到全部…...

得物面试:Redis用哈希槽,而不是一致性哈希,为什么?

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格&#xff0c;遇到很多很重要的面试题&#xff1a; Redis为何用哈希槽而不用一致性哈希&#xff1f; 最近…...

matlab发送串口数据,并进行串口数据头的添加,我们来看下pwm解析后并通过串口输出的效果

uintt16位的话会在上面前面加上00&#xff0c;16位的话一定是两个字节&#xff0c;一共16位的数据 如果是unint8的话就不会&#xff0c; 注意这里给的是13&#xff0c;但是现实的00 0D&#xff0c;这是大小端的问题&#xff0c;在matlanb里设置&#xff0c;我们就默认用这个模式…...

二分、快排、堆排与双指针

二分 int Binary_Search(vector<int> A,int key){int nA.size();int low0,highn-1,mid;while(low<high){mid(lowhigh)/2;if(A[mid]key)return mid;else if(A[mid]>key)highmid-1;elselowmid1; }return -1; }折半插入排序 ——找到第一个 ≥ \ge ≥tem的元素 voi…...

微信小程序步数返还的时间戳为什么返回的全是1970?

微信小程序步数返还的时间戳为什么返回的全是1970&#xff1f; 将返回的时间 乘以 1000 再 new Date() 转化就对了 微信返回的是秒S单位的&#xff0c;我们要转化为毫秒ms单位&#xff0c;才能进行格式化日期。 微信给我们下了个坑&#xff0c; 参考&#xff1a; https://d…...

Python函数——函数介绍

一、引言 在Python编程中&#xff0c;函数是构建高效代码的关键。通过创建可重用的代码块&#xff0c;我们可以使程序更加清晰、易读且易于维护。在本文中&#xff0c;我们将深入了解Python函数的基本概念及其特性。 二、Python函数的基本概念 函数是一段具有特定功能的代码块…...

【Linux系统化学习】文件重定向

目录 文件内核对象 文件描述符的分配规则 重定向 重定向的概念 dup2系统调用 输出重定向 追加重定向 输入重定向 stderr解析 重定向到同一个文件中 分离常规输出和错输出 文件内核对象 上篇文章中我们介绍到了操作系统中的文件&#xff0c;操作系统为了方…...

防火墙工作模式详解

防火墙工作模式是指防火墙在网络中的工作方式和策略。常见的防火墙工作模式包括以下几种&#xff1a; 1. 包过滤工作模式&#xff1a;根据事先确定的规则集合&#xff0c;对进出网络的网络包进行过滤和检查。根据规则&#xff0c;防火墙可以允许或阻止特定的网络流量。 2. 代…...

CCF编程能力等级认证GESP—C++6级—20231209

CCF编程能力等级认证GESP—C6级—20231209 单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09;判断题&#xff08;每题 2 分&#xff0c;共 20 分&#xff09;编程题 (每题 25 分&#xff0c;共 50 分)闯关游戏工作沟通 答案及解析单选题判断题编程题1编程题2 单选题…...

ES6 ~ ES11 学习笔记

课程地址 ES6 let let 不能重复声明变量&#xff08;var 可以&#xff09; let a; let b, c, d; let e 100; let f 521, g "atguigu", h [];let 具有块级作用域&#xff0c;内层变量外层无法访问 let 不存在变量提升&#xff08;运行前收集变量和函数&#…...

001 - Hugo, 创建一个网站

001 - Hugo, 创建一个网站安装hugoWindows系统Macos Hugo博客搭建初始化博客主题安装配置博客各个页面开始创作创建 GitHub Page 仓库本地调试和预览发布内容 教程及鸣谢文字教程视频教程 001 - Hugo, 创建一个网站 这篇文章假设你已经&#xff1a; 了解基本的终端命令行知识&…...

前端开发:Vue框架与前端部署

Vue Vue是一套前端框架&#xff0c;免除原生)avaScript中的DOM操作&#xff0c;简化书写。是基于MVVM(Model–View-ViewModel)思想&#xff0c;实现数据的双向绑定&#xff0c;将编程的关注点放在数据上。简单来说&#xff0c;就是数据变化的时候, 页面会自动刷新, 页面变化的时…...

【leetcode】深搜、暴搜、回溯、剪枝(C++)3

深搜、暴搜、回溯、剪枝&#xff08;C&#xff09;3 一、解数独1、题目描述2、代码3、解析 二、单词搜索1、题目描述2、代码3、解析 三、黄金矿工1、题目描述2、代码3、解析 四、不同路径III1、题目描述2、代码3、解析 一、解数独 1、题目描述 leetcode链接 2、代码 class…...

社区养老|社区养老服务系统|基于springboot社区养老服务系统设计与实现(源码+数据库+文档)

社区养老服务系统目录 目录 基于springboot社区养老服务系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员部分功能 &#xff08;1&#xff09; 用户管理 &#xff08;2&#xff09;服务种类管理 &#xff08;3&#xff09;社区服务管理 &#xff08…...

云计算基础-存储虚拟化(深信服aSAN分布式存储)

什么是存储虚拟化 分布式存储是利用虚拟化技术 “池化”集群存储卷内通用X86服务器中的本地硬盘&#xff0c;实现服务器存储资源的统一整合、管理及调度&#xff0c;最终向上层提供NFS、ISCSI存储接口&#xff0c;供虚拟机根据自身的存储需求自由分配使用资源池中的存储空间。…...

数学实验第三版(主编:李继成 赵小艳)课后练习答案(十二)(3)

实验十二&#xff1a;微分方程模型 练习三 1.分别用数值解命令ode23t和ode45 计算示例3中微分方程的数值解,同用命令ode23 算得的数值解以及解析解比较,哪种方法精度较高?你用什么方法比较它们之间的精度? clc;clear; f(x,y)2*yx2; figure(1) [x,y]ode23t(f,[1,2],1); plo…...

CSS Transition:为网页元素增添优雅过渡效果

随着互联网的发展&#xff0c;网页的视觉效果和用户体验变得尤为重要。CSS Transition作为一种能够让网页元素在状态改变时呈现平滑过渡效果的工具&#xff0c;受到了广大前端开发者的青睐。本文将详细介绍CSS Transition的基本概念、使用方法以及常见应用&#xff0c;帮助读者…...

JDK 17 新特性 (一)

既然 Springboot 3.0 强制使用 JDK 17 那就看看 JDK17 有哪些新特性吧 参考链接 介绍一下 新特性的历史渊源 JDK 17是Java Development Kit&#xff08;JDK&#xff09;的一个版本&#xff0c;它是Java编程语言的一种实现。JDK 17于2021年9月14日发布&#xff0c;并作为Java …...