• Java面试题,每日积累,每日更新


    目录

    JDK和JRE的区别

    什么是字节码文件

    基本数据类型的取值范围

    数据类型转换

    switch...case支持的数据类型

    while循环和do...while循环的区别 

    a+=1和a=a+1的区别,a++和++a的区别 

    &和&&,|和||的区别 

    访问权限修饰符都有哪些? 

    java的三大特征:

    方法的重载和重写的区别? 

    什么是对象深拷贝和浅复制

    Java中的关键字都有哪些?说说你知道哪些?

    this和super的区别

    数组的length和字符串的length()区别?

    ==和equals的区别

    基本数据类型和包装器类型的区别

    静态块和实例块的区别?

    Integer int1 = 200;Integer int2 = 200;int1 == int2结果.false

    Integer int3 = 1;Integer int4 = 1; int3 == int4结果?true

    final在java中的作用

    java中操作字符串的类都有哪些?他们之间的区别是什么?

    如何实现字符串反转?

    抽象类和抽象方法的联系

    抽象类和普通类的区别 

    可不可以用final修饰抽象类,为什么?

    为什么String类要用final修饰

    String的intren()方法有什么含义?

    抽象类和接口的区别 

    两个对象的 hashCode() 相同,则 equals() 也一定为 true吗?

    序列化

    序列化与反序列化

    如何实现序列化接口

    TCP/IP协议 

    为什么TCP要握手三次?

    为什么TCP挥手需要四次?

    TCP和UDP的区别

    集合:

    ArrayList和LinkedList的区别

    ArrayList和Vertor的区别

    List和Set区别

    HashSet和TreeSet的区别

    TreeSet的排序方式

    HashMap和Hashtable区别

    HashMap的内部结构

    异常

    异常的分类

    Throw和throws的区别

    异常处理

    编译期异常和运行期异常的区别

    finally和finalize的区别

    多线程

    线程的生命周期

    创建线程的方式:

    常用方法

    start与run的区别

    什么是守护线程? 怎么创建守护线程?

    线程通信

    sleep和wait的区别

    synchronized和 volatile的区别是什么

    线程的优先级:

    循环遍历:

    IO流/File类

    关于流的flush()方法, 以下哪个正确?A

    JDK5之后出现的功能

    JDK7之后的功能

    JDK8之后的功能

    JDK10之后的功能

    JDK13之后的功能


    JDK和JRE的区别

    JDK是java开发工具包,提供了java的开发环境和运行环境

    JRE是java运行环境,为java运行提供了所需要的环境

    具体来说JDK包含了JRE同时还包括编译java源码的编译器,还包括很多的java调试分析工具

    如果要运行java程序只需要安装JRE就可以了,如果要编写java程序,则需要安装JDK

    什么是字节码文件

    首先java程序的源文件就是.java文件, 代码写在.java文件中,.java文件通过编译器(javac命令)编译生成了字节码文件,也就是.class文件,通过解释器或者说是jvm虚拟机执行字节码文件。

    基本数据类型的取值范围

    字节型byte-128~1278位
    短整型short-2^15~2^15-116位
    整型int-2^31~2^31-132位
    长整型long-2^63~2^63-164位
    短浮点型float32位
    长浮点型double64位
    字符型char0~2^1616位
    布尔型boolean8位

    数据类型转换

    byte

    由低到高---自动转型

    由高到低---强制类型转换:

            int i = (int)short 

    switch...case支持的数据类型

    char、byte、short、int、枚举(JDK5之后),String(JDK7以后)

    while循环和do...while循环的区别 

    while循环先判断条件,如果条件不满足,一次也不执行

    do...while循环先执行,在判断,无论条件是否满足,循环都至少执行一次

    a+=1和a=a+1的区别,a++和++a的区别 

    a=a+1会涉及到数据类型转换的问题,a+=1和a++会自动处理数据类型转换的问题

    a++是先附值后运算,++a是先运算后附值

    &和&&,|和||的区别 

    &&是短路的意思,遇见false就停止了判断,无论之后的条件是什么,是否有误,都不会再执行了

    &则是会把所有的条件都判断一便,|和||也一样

    访问权限修饰符都有哪些? 

    public公有的,在当前工程的任意位置都可以访问到
    default默认的,在同一包下可以访问
    protected受保护的,在不同包下的子类可以访问
    private私有的,只有当前类可以访问

                                                    private

    java的三大特征:

    封装:把客观事物抽象成类,让所有的属性私有化。让可信的类或者对象操作。保证内部结构安全;屏蔽复杂,暴露简单(对功能的封装)

    继承:子类继承父类,在无需重新编写原来的类的情况下对原来的类的功能进行扩展,使代码得到复用;主要是为了方法覆盖的重写和多态机制的前提

    多态: 多种形态,编译期的一种形态。父类引用指向子类对象;前提:存在继承关系,子类重写父类方法。目的是降低程序耦合提高程序的扩展

    方法的重载和重写的区别? 

    方法的重载

    方法的重写
    英文

    Overload

    Override

    发生位置

    同一个类中

    发生在继承或实现接口中

    访问权限

    没有要求

    重写的方法必须大于被重写的方法的访问权限

    返回值

    没有要求

    必须相同

    方法名

    必须相同

    必须相同

    参数列表

    参数个数,参数顺序,参数类型其中一个必须不同

    必须相同

    异常情况

    没有要求

    重写的方法不能抛出比被重写方法更大的异常

    什么是对象深拷贝和浅复制

    浅复制:只对对象及变量值进行复制,引用对象地址不变

    深拷贝:不仅对象及变量值进行复制,引用对象地址也进行复制
    将一个对象的引用复制给另一个对象,一共有三种方式:
    一:直接赋值: a和 a2 指向的是同一个对象 , a2 变化的时候, 里面的成员变量也会 跟着变化
    1. public class Test02 {
    2. public static void main(String[] args) {
    3. A a = new A();
    4. a.setNumber(1008611);
    5. A a2 =a;
    6. System.out.println(a.getNumber());
    7. System.out.println(a2.getNumber());
    8. a2.setNumber(1001011);
    9. System.out.println(a.getNumber());
    10. System.out.println(a2.getNumber());
    11. }
    12. }
    13. class A{
    14. private static int number;
    15. public int getNumber(){
    16. return number;
    17. }
    18. public void setNumber(int number){
    19. this.number=number;
    20. }
    21. }

    结果:

    1008611

    1008611

    1001011

    1001011

    二:浅复制(复制引用地址但不复制引用的对象)

    1. class Resume implements Cloneable{
    2. public Object clone() {
    3. try {
    4. return (Resume)super.clone();
    5. } catch (Exception e) {
    6. e.printStackTrace();
    7. }
    8. return null;
    9. }
    10. }

    三:深拷贝 (不仅复制对象本身,而且复制对象包含的引用指向的所有对象

    1. class Student implements Cloneable {
    2. String name;
    3. int age;
    4. Professor p;
    5. public Object clone() {
    6. Student o = null;
    7. try {
    8. o = (Student) super.clone();
    9. } catch (CloneNotSupportedException e) {
    10. System.out.println(e.toString());
    11. }
    12. o.p = (Professor) p.clone();
    13. return o;
    14. }
    15. }

    Java中的关键字都有哪些?说说你知道哪些?

    还有两个保留字:const+goto

    this和super的区别

    this

    super

    对象

    代表本类对象

    不能代表任何对象

    属性

    调用本类属性

    调用父类属性

    方法

    调用本类方法

    调用父类方法

    构造器

    调用本类构造器

    调用父类构造器

    在调用构造器时

    需要在调用本类构造器中的第一条语句

    在调用父类构造器后,也需要是构造器中的第一条语句

    数组的length和字符串的length()区别?

    数组的lenth是数组的属性,字符串的length()是String的一个方法

    ==和equals的区别

    在基本类型和引用数据类型时==的效果是不同的,在基本数据类型中,一样的数据他们指向了同一个引用(地址)。所以==可以相同,但引用数据类型是每一个都开辟了自己的空间,所以他们的地址是不一样的,别看他们的值一样。

    总体来说:==是一个比较运算符。

                      equals是一个方法。

    如果是Object类中的equals,没有区别,都是比较地址。

    如果是其他类的equals,String。。。,equals是比较内容,==永远比较的是地址。

    基本数据类型和包装器类型的区别

    基本数据类型是有默认值的,int0 double0.0 boolean false..

    包装器类型默认值为null

    静态块和实例块的区别?

    静态块是一个类被加载时会被调用一次,通常都是做一些初始化的工作

    实例块是每次创建实例,都会被调用一次

    执行顺序:

    当没有继承关系时,就一个类:静态块---实例块---构造器

    当有继承关系时,父类静态块---子类静态块---父类实例块---父类构造器---子类实例块---子类构造器

    Integer int1 = 200;Integer int2 = 200;int1 == int2结果.false

    Integer int3 = 1;Integer int4 = 1; int3 == int4结果?true

    在Integer类中存在一个-128~127的缓冲区,会把区间的数字缓冲起来,当比较时,会先去缓冲区取数据,如果缓冲区没有响应的值,则去new Integer(),一旦出现new,用==比较是比较地址,就是返回false。我们在比较时,统一使用equals方法来比较。

    final在java中的作用

    final修饰的类叫最终类,该类不能被继承

    final修饰的方法不能被重写

    final修饰的变量叫常量,常量必须初始化,初始化之后不可被修

    java中操作字符串的类都有哪些?他们之间的区别是什么?

    String,StringBuffer,StringBuilder.

    String是不可变的对象,每次操作都会产生一个新的String对象,然后指针会指向新的String对象

    StringBuffer和StringBuilder是可变的字符序列,可以在原有对象的基础上进行操作,

    StringBuffer线程是安全的,但是性能比较弱,多线程环境推荐使用

    StringBuilder是非线程安全,但是性能高,单线程环境推荐使

    如何实现字符串反转?

    利用StringBuilder或StringBuffer的reverse()方法

    抽象类和抽象方法的联系

    抽象类中不一定要有抽象方法,但是抽象方法一定是在抽象类中

    抽象类和普通类的区别 

    普通类里不能有抽象方法,抽象类里不能实例化

    可不可以用final修饰抽象类,为什么?

    抽象类不能被final修饰,定义抽象类就是为了让他可以被其他类继承或者是实现接口,如果被final修饰了,那还怎么改变,就会冲突,所以final不能修饰抽象类

    为什么String类要用final修饰

    安全:不可修改

    高效:用到了常量池,String s1 = "java" String s2 = "java" s1和s2指向常量池“java"

    String的intren()方法有什么含义?

    将字符串放入常量池。

    String s1 = new String();这种方式是把s1放进堆里。

    String s2="";这种方式是把字符串s2放进常量池里。

    s1.intren()就是把s1放进常量池里。

    抽象类和接口的区别 

    抽象类中可以放任意的结构。只能单继承

    抽象类的子类使用extends继承,接口必须使用implements来实现

    抽象类可以有构造函数,而接口不能有

    java只能单继承,但可以多实现,—-有多个接口但是只能有一个父类

    接口中的方法默认是public修饰的,抽象类中的方法可以是任意

    接口中只能放常量,抽象方法,默认方法,静态方法(JDK8以后)。可以多实现。接口和接口之间可以多继承。

    两个对象的 hashCode() 相同,则 equals() 也一定为 true吗?

    不对。hashCode() 和 equals() 之间的关系如下:

    当有 a.equals(b) == true 时,则 a.hashCode() == b.hashCode() 必然成立,

    反过来,当 a.hashCode() == b.hashCode() 时,a.equals(b) 不一定为 true。

    序列化

    序列化与反序列化

    序列化:把一个对象按照某种规则以及某个版本号保存到硬盘上的某个文件。一个对象对应一个文件。

    反序列化:把一个文件根据某种规则以及当时序列化时使用的版本号来读取对象,读到内存中。

    如何实现序列化接口

    1.序列化的类要实现Serializable接口

    2.添加一个序列号:private static final long serialVersionUID = -6849794470754667710L;

    TCP/IP协议 

    为什么TCP要握手三次?

    TCP是可靠的传输控制协议,三次握手能保证数据可靠传输又能提高传输效率

    如果TCP握手二次:

            客户端发送syn,进入到closeed状态,服务端一直等待,这样浪费了服务器端资源。

    如果TCP握手四次:

            1. client给 server发送SYN同步报文;

            2. server收到SYN后,给 client回复ACK确认报文;

            3. server给 client发送SYN同步报文;

            4. client给 server发送ACK确认报文。

            相当于服务器多发了一次TCP报文,降低了连接速度和效率。

    为什么TCP挥手需要四次?

    因为TCP连接是全双工的网络协议,允许同时通信的双方同时进行数据的收发,同样也允许收发 两个方向的连接被独立关闭,关闭TCP连接需要进行四次连接,每次关闭一个方向上的连接需要 FIN和ACK两次握手。

    TCP和UDP的区别

    TCP和UDP都属于传输层协议,它们之间的区别在于

    TCP是面向连接的;UDP是无连接的。

    TCP是可靠的;UDP是不可靠的

    TCP只支持点对点通信;UDP支持一对一、一对多、多对一、多对多的通信模式。

    TCP是面向字节流的;UDP是面向报文的。

    TCP有拥塞控制机制;UDP没有拥塞控制,适合媒体通信。

    TCP首部开销(20个字节),比UDP的首部开销(8个字节)要大.

    集合:

    ArrayList和LinkedList的区别

    ArrayList底层是数组,查找操作块,增加或删除操作慢

    LinkedList底层是链表,查找操作慢,增加或删除操作块

    相同点:都是线程异步的不安全线程集合,都实现List接口,继承了Collection

    ArrayList和Vertor的区别

    ArrayList:线程异步,线程不安全,性能高

    Vertor:线程同步,线程安全,性能低

    相同点:都实现了List接口,都是有序集合。

    List和Set区别

    List:有顺序,元素可以重复,顺序指的是添加的先后顺序

    Set:没有顺序,元素不可重复

    Set集合如何确保数据的不重复

    重写equals()和hashCode()方法

    HashSet和TreeSet的区别

    HashSet:底层是HashMap,往HashSet集合中存储元素,实际上是存放到HashMap集合的key部分,并且不能保证顺序。

    TreeSet:按照预定规则排序,继承了SortedSet接口的特点(无序不可重复可自动排序),底层是二叉树,TreeSet底层实例化了TreeMap,实际上是存放到TreeMap集合的key部分。

    TreeSet的排序方式

    1.自然排序:实现Comparable接口,重写compareTo方法

    2.定制排序(临时排序):实现Comparator接口,重写compare方法

    HashMap和Hashtable区别

    HashMap线程不安全,效率高,key值可以为null。

    Hashtable线程安全,效率低,key值不可以为null。 

    HashMap的内部结构

    JDK7之前:数组+链表

    JDK8之后:数组+链表+红黑树

    异常

    异常的分类

    Throwable是java语言中所有错误或异常的超类。下一层分为Error和Exception

    Error类是指java运行时系统的内部错误和资源耗尽错误。应用程序不会抛出该类对象。如果出现了这样的错误,除了告知用户,剩下的就是尽力使程序安全的终止。

    Exception类是异常

            编译期异常:写代码时出现的异常:

    IOException输入输出异常
    FileNotFoundException文件未找到异常
    ClassNotFoundException类找不到异常
    EOFException当输入过程中意外到达文件或流的末尾时异常
    SQLException提供有关数据库访问错误或其他错误的信息异常

            运行时异常:写代码时出现的异常

    NullPointerException空指针异常
    ArithmeticException运算非法异常
    IndexOutOfBoundsException数组越界异常
    ClassCastException类转换异常
    ArrayStoreException数据存储异常,操作数组时类型不一致
    BufferOverflowException字节溢出异常---IO流操作

    Throw和throws的区别

    位置不同:throw是方法内容,throws方法声明

    功能不同:throws表示出现异常的一种可能性,声明异常并不一定会发生这些异常

                      throw则是抛出异常,执行throw则一定抛出了某种异常

    异常处理

    try..(有可能出现的异常的代码)..catch..(出现异常时要执行的代码/通常用来捕获异常,抛出异常)..finally(无论什么情况都会执行的代码)

    try是有可能出现异常的代码

    catch说明:

            catch是可以有多个的

            catch中捕获的异常是有顺序的,先要捕获小的,后捕获大的

            catch括号中写的是一个异常对象,这个异常对象在出现相应的异常时被实例化

    finally里的语句在try...catch之后无论是否有异常他都会执行

    编译期异常和运行期异常的区别

    编译期异常在写代码时期抛出的异常,如果不处理,编译不通过。

    运行期异常只要不运行,就不报错。

    finally和finalize的区别

    finally异常处理的一个结构,放在finally中的代码无论是否出现异常都会执行。

    finalize()是Object类的一个方法,垃圾回收的方法,JDK9已过时。

    多线程

    线程的生命周期

    1.新建:当线程对象创建后,就进入了新建状态;eg: Thread thread = new Thread();

    2.就绪:当调用线程对象的start()方法,线程就进入了就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了thread.start()此线程立即就会执行;

    3.运行:当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。就绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中。

    4.阻塞:处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,知道其进入到就绪状态,才有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:

            1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;

            2.同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;

            3.其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

    5.死亡:线程执行完了或者因异常退出了run()方法,该线程结束生命周期.

    创建线程的方式:

    继承Thread类

    重写run方法,调用start方法启动线程

    重写Runnable接口

    重写run方法,把当前的实现类包装成Thread类对象,调用start方法

    实现了Callable接口

    重写call方法,把当前的实现类先包装成Runnable,再包装成Thread,再调用start方法

    线程池:

            开发中,基本上涉及到多线程,一定会用线程池。

            但是我们不会用JDK提供的线程池(阿里规约的约定)。

            我们一般会自定义线程池。

    synchronized同步锁

    ReentrantLock锁

    Lock锁

    Lock锁和synchronized的区别?

    Lock是手动上锁,手动解锁。

    synchronized是全自动

    常用方法

    sleep:线程休眠

    interrupt:线程中断

    join:线程加入

    yield:释放CPU执行权

    currentThread:静态方法,获取当前正在执行的线程
    getId():返回此线程的唯一标识
    setName(String):设置当前线程的name
    getName():获取当前线程的name
    getPriority():获取当前线程的优先级
    setPriority(int):设置当前线程的优先级
    getState():获取当前线程的声明周期
    interrupt():中断线程的执行
    interrupted():查看当前线程是否中断 

    start与run的区别

    1.start() 方法来启动线程,真正实现了多线程运行。
    2.Run()方法执行线程的任务

    什么是守护线程? 怎么创建守护线程?

    也叫后台线程,它有一个特性,即 为用户线程 提供 公共服务, 垃圾回收线程就是一个经典的守护线程。
    线程.setDaemon(true);

    线程通信

    wait:释放CPU资源,释放锁
    notify:唤醒等待中的线程
    notifyAll:唤醒等待中的所有线程

    死锁:互相拿着对方需要的资源不释放。

    sleep和wait的区别

    1、这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类。

    2.最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。

    3、使用范围:wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用

    4、sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常

    总结:

    两者都可以暂停线程的执行。

    sleep()方法是属于Thread类中的。而wait()方法是属于Object类中的。

    Wait 通常被用于线程间交互/通信,sleep 通常被用于暂停执行。

    sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。

    在调用sleep()方法的过程中,线程不会释放对象锁。

    而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备,获取对象锁进入运行状态。线程不会自动苏醒。

    synchronized和 volatile的区别是什么

    volatile 是变量修饰符: synchronized 是修饰类、方法、代码段
    volatile 仅能实现变量的修改可见性,不能保证原子性: 而 synchronized 则可以保证变量的修改可见性和原子性 )
    volatile 不会线程的阻塞: synchronized 可能会造成线程的阻塞

    线程的优先级:

    整型。1~10的整数。

    1. public static final int MIN_PRIORITY = 1;
    2. /**
    3. * The default priority that is assigned to a thread.
    4. */
    5. public static final int NORM_PRIORITY = 5;
    6. /**
    7. * The maximum priority that a thread can have.
    8. */
    9. public static final int MAX_PRIORITY = 10;

    循环遍历:

    List:

    1. // 1.for循环
    2. for (int i = 0; i < list.size(); i++) {
    3. // TODO
    4. }
    5. // 2.增强for循环
    6. for (String s : list) {
    7. // TODO
    8. }
    9. // 3.迭代器
    10. Iterator<String> iterator = list.iterator();
    11. while(iterator.hasNext()) {
    12. System.out.println(iterator.next());
    13. }

    Set:

    1. // 1.增强for循环
    2. for (String s : set) {
    3. // TODO
    4. }
    5. // 2.迭代器
    6. Iterator<String> iterator = set.iterator();
    7. while(iterator.hasNext()){
    8. System.out.println(iterator.next());
    9. }

    Map:

    1. // 1.使用keySet先拿到所有的key,再根据key获取value
    2. Set<String> keys = map.keySet();
    3. for (String key : keys) {
    4. System.out.println(key + "->" + map.get(key));
    5. }
    6. // 2.使用内部类Entry(推荐)
    7. for (Map.Entry<String, String> entry : map.entrySet()) {
    8. System.out.println(entry.getKey() + entry.getValue());
    9. }

    IO流/File类

    File类只能操作文件,不能操作文件的内容

    输入流(读):把磁盘上的数据读取到内存中

    输出流(写):把内存中的数据写出到磁盘上

    类型输入流输出流
    字节流InputStreamOutputStream
    字符流ReaderWriter
    缓冲字节流BufferedInputStreamBufferedOutputStream
    缓冲字符流BufferedReaderBufferedWriter
    数据流DataInputStreamDataOutputStream
    对象流ObjectInputStreamObjectOutputStream
    文件字节流FileInputStreamFileOutputStream
    文件字符流FileReaderFileWriter

    字节流:可以操作二进制文件->所有文件

    字符流:只能操作纯文本文件

    关于流的flush()方法, 以下哪个正确?A

    A. flush()方法是输出流的方法,其作用是强制将流中的缓存输出
    B. flush()方法是字节流特有的方法, 其作用是清空流中的数据【close()】---flush()是输出流特有的方法
    C. flush()方法是字符流特有的方法----同上
    D. 由于输入流没有缓存,因此输入流没有flush()方法-----输入流是有缓存的

    JDK5之后出现的功能

    1. 增强for循环
    2. 枚举
    3. 泛型
    4. 自动装箱/自动拆箱
    5. 包装器
    6. Callable接口
    7. StringBuilder

    JDK7之后的功能

    1. 类型推断
    2. try中可以创建对象
    3. switch...case支持String
    4. Objects类

    JDK8之后的功能

    1. 函数式接口
    2. 箭头函数(lambda表达式)
    3. 断言
    4. 接口的改变
      1. 默认方法
      2. 静态方法
    5. HashMap内部结构(数组+链表+红黑树)
    6. Stream式编程

    JDK10之后的功能

          1.类型推断(定义变量可以用var)

    JDK13之后的功能

           1.文档字符串

  • 相关阅读:
    【个人博客搭建】(24)统一api接口返回格式
    面试官: AMS在Android起到什么作用,简单的分析下Android的源码
    【Spring源码】18. factory-method创建对象关键函数详解:instantiateUsingFactoryMethod()
    2022年Java后端面试题,备战秋招,查缺补漏,吃透16套专题技术栈
    webpack 打包 CSS 文件,解析器兼容性问题
    BP神经网络算法基本原理,bp神经网络算法详解
    JavaScript或其他编程语言中关于函数的各种高级特性和设计模式
    Polygon zkEVM工具——PIL和CIRCOM
    骨传导蓝牙耳机排行榜,精选五款骨传导耳机推荐!
    【ntp】ntpdate&ntpd
  • 原文地址:https://blog.csdn.net/weixin_49627122/article/details/126272773