Java基础常考知识点(基础、集合、异常、JVM)

作者:逍遥Sean
简介:一个主修Java的Web网站\游戏服务器后端开发者
主页:https://blog.csdn.net/Ureliable
觉得博主文章不错的话,可以三连支持一下~ 如有需要我的支持,请私信或评论留言!

Java基础常考知识点

  • 基础
    • JDK、JRE、JVM之间的区别
    • hashCode()与equals()之间的关系
    • String、StringBuffer、StringBuilder的区别
    • 泛型中extends和super的区别
    • ==和equals⽅法的区别
    • 重载和重写的区别
    • 深拷⻉和浅拷⻉
    • 什么是字节码?采⽤字节码的好处是什么?
    • Java中有哪些类加载器
    • 说说类加载器双亲委派模型
  • 集合
    • List和Set的区别
    • ArrayList和LinkedList区别
    • 谈谈ConcurrentHashMap的扩容机制
    • Jdk1.7到Jdk1.8 HashMap 发⽣了什么变化(底层)?
    • 说⼀下HashMap的Put⽅法
    • HashMap的扩容机制原理
    • CopyOnWriteArrayList的底层原理是怎样的
  • 异常
    • Java中的异常体系是怎样的
    • 在Java的异常处理机制中,什么时候应该抛出异常,什么时候捕获异常?
  • JVM
    • JVM中哪些是线程共享区
    • 项⽬如何排查JVM问题
    • ⼀个对象从加载到JVM,再到被GC清除,都经历了什么过程?
    • 怎么确定⼀个对象到底是不是垃圾?
    • JVM有哪些垃圾回收算法?
    • 什么是STW?

本文收集Java核心的面试常考知识点,码起面试之前复习!!!

基础

JDK、JRE、JVM之间的区别

  • JDK(Java SE Development Kit),Java标准开发包,它提供了编译、运⾏Java程序所需的各种⼯具和资源,包括Java编译器、Java运⾏时环境,以及常⽤的Java类库等
  • JRE( Java Runtime Environment) ,Java运⾏环境,⽤于运⾏Java的字节码⽂件。JRE中包括了JVM以及JVM⼯作所需要的类库,普通⽤户⽽只需要安装JRE来运⾏Java程序,⽽程序开发者必须安装JDK来编译、调试程序。
  • JVM(Java Virtual Mechinal),Java虚拟机,是JRE的⼀部分,它是整个java实现跨平台的最核⼼的部分,负责运⾏字节码⽂件。

我们写Java代码,⽤txt就可以写,但是写出来的Java代码,想要运⾏,需要先编译成字节码,那就需要编译器,⽽JDK中就包含了编译器javac,编译之后的字节码,想要运⾏,就需要⼀个可以执⾏字节码的程序,这个程序就是JVM(Java虚拟机),专⻔⽤来执⾏Java字节码的。

如果我们要开发Java程序,那就需要JDK,因为要编译Java源⽂件。

如果我们只想运⾏已经编译好的Java字节码⽂件,也就是*.class⽂件,那么就只需要JRE。JDK中包含了JRE,JRE中包含了JVM。

另外,JVM在执⾏Java字节码时,需要把字节码解释为机器指令,⽽不同操作系统的机器指令是有可能不⼀样的,所以就导致不同操作系统上的JVM是不⼀样的,所以我们在安装JDK时需要选择操作系统。另外,JVM是⽤来执⾏Java字节码的,所以凡是某个代码编译之后是Java字节码,那就都能在JVM上运⾏,⽐如Apache Groovy, Scala and Kotlin 等等。

hashCode()与equals()之间的关系

在Java中,每个对象都可以调⽤⾃⼰的hashCode()⽅法得到⾃⼰的哈希值(hashCode),相当于对象的指纹信息,通常来说世界上没有完全相同的两个指纹,但是在Java中做不到这么绝对,但是我们仍然可以利⽤hashCode来做⼀些提前的判断,⽐如:

  • 如果两个对象的hashCode不相同,那么这两个对象肯定不同的两个对象
  • 如果两个对象的hashCode相同,不代表这两个对象⼀定是同⼀个对象,也可能是两个对象
  • 如果两个对象相等,那么他们的hashCode就⼀定相同

在Java的⼀些集合类的实现中,在⽐较两个对象是否相等时,会根据上⾯的原则,会先调⽤对象的hashCode()⽅法得到hashCode进⾏⽐较,如果hashCode不相同,就可以直接认为这两个对象不相同,如果hashCode相同,那么就会进⼀步调⽤equals()⽅法进⾏⽐较。⽽equals()⽅法,就是⽤来最终确定两个对象是不是相等的,通常equals⽅法的实现会⽐较重,逻辑⽐较多,⽽hashCode()主要就是得到⼀个哈希值,实际上就⼀个数字,相对⽽⾔⽐较轻,所以在⽐较两个对象时,通常都会先根据hashCode想⽐较⼀下。
所以我们就需要注意,如果我们重写了equals()⽅法,那么就要注意hashCode()⽅法,⼀定要保证能遵守上述规则。

String、StringBuffer、StringBuilder的区别

  1. String是不可变的,如果尝试去修改,会新⽣成⼀个字符串对象,StringBuffer和StringBuilder是可变的
  2. StringBuffer是线程安全的,StringBuilder是线程不安全的,所以在单线程环境下StringBuilder效率会更⾼

泛型中extends和super的区别

  1. <? extends T>表示包括T在内的任何T的⼦类
  2. <? super T>表示包括T在内的任何T的⽗类

==和equals⽅法的区别

  • ==:如果是基本数据类型,⽐较是值,如果是引⽤类型,⽐较的是引⽤地址
  • equals:具体看各个类重写equals⽅法之后的⽐较逻辑,⽐如String类,虽然是引⽤类型,但是String类中重写了equals⽅法,⽅法内部⽐较的是字符串中的各个字符是否全部相等。

重载和重写的区别

  • 重载(Overload): 在⼀个类中,同名的⽅法如果有不同的参数列表(⽐如参数类型不同、参数个数不同)则视为重载。
  • 重写(Override): 从字⾯上看,重写就是 重新写⼀遍的意思。其实就是在⼦类中把⽗类本身有的⽅法重新写⼀遍。⼦类继承了⽗类的⽅法,但有时⼦类并不想原封不动的继承⽗类中的某个⽅法,所以在⽅法名,参数列表,返回类型都相同(⼦类中⽅法的返回值可以是⽗类中⽅法返回值的⼦类)的情况下, 对⽅法体进⾏修改,这就是重写。但要注意⼦类⽅法的访问修饰权限不能⼩于⽗类的。

深拷⻉和浅拷⻉

深拷⻉和浅拷⻉就是指对象的拷⻉,⼀个对象中存在两种类型的属性,⼀种是基本数据类型,⼀种是实例对象的引⽤。

  1. 浅拷⻉是指,只会拷⻉基本数据类型的值,以及实例对象的引⽤地址,并不会复制⼀份引⽤地址所指向的对象,也就是浅拷⻉出来的对象,内部的类属性指向的是同⼀个对象
  2. 深拷⻉是指,既会拷⻉基本数据类型的值,也会针对实例对象的引⽤地址所指向的对象进⾏复制,深拷⻉出来的对象,内部的属性指向的不是同⼀个对象

什么是字节码?采⽤字节码的好处是什么?

编译器(javac)将Java源⽂件(.java)⽂件编译成为字节码⽂件(.class),可以做到⼀次编译到处运⾏,windows上编译好的class⽂件,可以直接在linux上运⾏,通过这种⽅式做到跨平台,不过Java的跨平台有⼀个前提条件,就是不同的操作系统上安装的JDK或JRE是不⼀样的,虽然字节码是通⽤的,但是需要把字节码解释成各个操作系统的机器码是需要不同的解释器的,所以针对各个操作系统需要有各⾃的JDK或JRE。

采⽤字节码的好处,⼀⽅⾯实现了跨平台,另外⼀⽅⾯也提⾼了代码执⾏的性能,编译器在编译源代码时可以做⼀些编译期的优化,⽐如锁消除、标量替换、⽅法内联等。

Java中有哪些类加载器

JDK⾃带有三个类加载器:bootstrap ClassLoader、ExtClassLoader、AppClassLoader。

  • BootStrapClassLoader是ExtClassLoader的⽗类加载器,默认负责加载%JAVA_HOME%lib下的jar包和class⽂件。
  • ExtClassLoader是AppClassLoader的⽗类加载器,负责加载%JAVA_HOME%/lib/ext⽂件夹下的jar包和class类。
  • AppClassLoader是⾃定义类加载器的⽗类,负责加载classpath下的类⽂件。

说说类加载器双亲委派模型

JVM中存在三个默认的类加载器:

  1. BootstrapClassLoader
  2. ExtClassLoader
  3. AppClassLoader

AppClassLoader的⽗加载器是ExtClassLoader,ExtClassLoader的⽗加载器是BootstrapClassLoader。

JVM在加载⼀个类时,会调⽤AppClassLoader的loadClass⽅法来加载这个类,不过在这个⽅法中,会先使⽤ExtClassLoader的loadClass⽅法来加载类,同样ExtClassLoader的loadClass⽅法中会先使⽤
BootstrapClassLoader来加载类,如果BootstrapClassLoader加载到了就直接成功,如果BootstrapClassLoader没有加载到,那么ExtClassLoader就会⾃⼰尝试加载该类,如果没有加载到,那么则会由AppClassLoader来加载这个类。

所以,双亲委派指得是,JVM在加载类时,会委派给Ext和Bootstrap进⾏加载,如果没加载到才由⾃⼰进⾏加载。

集合

List和Set的区别

  • List:有序,按对象插⼊的顺序保存对象,可重复,允许多个Null元素对象,可以使⽤Iterator取出所有元素,在逐⼀遍历,还可以使⽤get(int index)获取指定下标的元素
  • Set:⽆序,不可重复,最多允许有⼀个Null元素对象,取元素时只能⽤Iterator接⼝取得所有元素,在逐⼀遍历各个元素

ArrayList和LinkedList区别

  1. ⾸先,他们的底层数据结构不同,ArrayList底层是基于数组实现的,LinkedList底层是基于链表实现的
  2. 由于底层数据结构不同,他们所适⽤的场景也不同,ArrayList更适合随机查找,LinkedList更适合删除和添加,查询、添加、删除的时间复杂度不同
  3. 另外ArrayList和LinkedList都实现了List接⼝,但是LinkedList还额外实现了Deque接⼝,所以LinkedList还可以当做队列来使⽤

谈谈ConcurrentHashMap的扩容机制

1.7版本

  1. 1.7版本的ConcurrentHashMap是基于Segment分段实现的
  2. 每个Segment相对于⼀个⼩型的HashMap
  3. 每个Segment内部会进⾏扩容,和HashMap的扩容逻辑类似
  4. 先⽣成新的数组,然后转移元素到新数组中
  5. 扩容的判断也是每个Segment内部单独判断的,判断是否超过阈值

1.8版本

  1. 1.8版本的ConcurrentHashMap不再基于Segment实现
  2. 当某个线程进⾏put时,如果发现ConcurrentHashMap正在进⾏扩容那么该线程⼀起进⾏扩容
  3. 如果某个线程put时,发现没有正在进⾏扩容,则将key-value添加到ConcurrentHashMap中,然 后判断是否超过阈值,超过了则进⾏扩容
  4. ConcurrentHashMap是⽀持多个线程同时扩容的
  5. 扩容之前也先⽣成⼀个新的数组
  6. 在转移元素时,先将原数组分组,将每组分给不同的线程来进⾏元素的转移,每个线程负责⼀组或 多组的元素转移⼯作

Jdk1.7到Jdk1.8 HashMap 发⽣了什么变化(底层)?

  1. 1.7中底层是数组+链表,1.8中底层是数组+链表+红⿊树,加红⿊树的⽬的是提⾼HashMap插⼊和查询整体效率
  2. 1.7中链表插⼊使⽤的是头插法,1.8中链表插⼊使⽤的是尾插法,因为1.8中插⼊key和value时需要判断链表元素个数,所以需要遍历链表统计链表元素个数,所以正好就直接使⽤尾插法
  3. 1.7中哈希算法⽐较复杂,存在各种右移与异或运算,1.8中进⾏了简化,因为复杂的哈希算法的⽬的就是提⾼散列性,来提供HashMap的整体效率,⽽1.8中新增了红⿊树,所以可以适当的简化哈希算法,节省CPU资源

说⼀下HashMap的Put⽅法

先说HashMap的Put⽅法的⼤体流程:

  1. 根据Key通过哈希算法与与运算得出数组下标
  2. 如果数组下标位置元素为空,则将key和value封装为Entry对象(JDK1.7中是Entry对象,JDK1.8中
    是Node对象)并放⼊该位置
  3. 如果数组下标位置元素不为空,则要分情况讨论

a. 如果是JDK1.7,则先判断是否需要扩容,如果要扩容就进⾏扩容,如果不⽤扩容就⽣成Entry对 象,并使⽤头插法添加到当前位置的链表中

b. 如果是JDK1.8,则会先判断当前位置上的Node的类型,看是红⿊树Node,还是链表Node
ⅰ.如果是红⿊树Node,则将key和value封装为⼀个红⿊树节点并添加到红⿊树中去,在这个过程中会判断红⿊树中是否存在当前key,如果存在则更新value
ⅱ. 如果此位置上的Node对象是链表节点,则将key和value封装为⼀个链表Node并通过尾插法插⼊到链表的最后位置去,因为是尾插法,所以需要遍历链表,在遍历链表的过程中会判断是否存在当前key,如果存在则更新value,当遍历完链表后,将新链表Node插⼊到链表中,插⼊到链表后,会看当前链表的节点个数,如果⼤于等于8,那么则会将该链表转成 红⿊树
ⅲ. 将key和value封装为Node插⼊到链表或红⿊树中后,再判断是否需要进⾏扩容,如果需要 就扩容,如果不需要就结束PUT⽅法

HashMap的扩容机制原理

1.7版本

1. 先⽣成新数组
2. 遍历⽼数组中的每个位置上的链表上的每个元素
3. 取每个元素的key,并基于新数组⻓度,计算出每个元素在新数组中的下标
4. 将元素添加到新数组中去
5. 所有元素转移完了之后,将新数组赋值给HashMap对象的table属性

1.8版本

1. 先⽣成新数组
2. 遍历⽼数组中的每个位置上的链表或红⿊树
3. 如果是链表,则直接将链表中的每个元素重新计算下标,并添加到新数组中去
4. 如果是红⿊树,则先遍历红⿊树,先计算出红⿊树中每个元素对应在新数组中的下标位置a. 统计每个下标位置的元素个数b. 如果该位置下的元素个数超过了8,则⽣成⼀个新的红⿊树,并将根节点的添加到新数组的对应位置c. 如果该位置下的元素个数没有超过8,那么则⽣成⼀个链表,并将链表的头节点添加到新数组的对应位置
5. 所有元素转移完了之后,将新数组赋值给HashMap对象的table属性

CopyOnWriteArrayList的底层原理是怎样的

  1. ⾸先CopyOnWriteArrayList内部也是⽤过数组来实现的,在向CopyOnWriteArrayList添加元素时,会复制⼀个新的数组,写操作在新数组上进⾏,读操作在原数组上进⾏
  2. 并且,写操作会加锁,防⽌出现并发写⼊丢失数据的问题
  3. 写操作结束之后会把原数组指向新数组
  4. CopyOnWriteArrayList允许在写操作时来读取数据,⼤⼤提⾼了读的性能,因此适合读多写少的应⽤场景,但是CopyOnWriteArrayList会⽐较占内存,同时可能读到的数据不是实时最新的数据,所以不适合实时性要求很⾼的场景

异常

Java中的异常体系是怎样的

  • Java中的所有异常都来⾃顶级⽗类Throwable。
  • Throwable下有两个⼦类Exception和Error。
  • Error表示⾮常严重的错误,⽐如java.lang.StackOverFlowError和Java.lang.OutOfMemoryError,通常这些错误出现时,仅仅想靠程序⾃⼰是解决不了的,可能是虚拟机、磁盘、操作系统层⾯出现的问题了,所以通常也不建议在代码中去捕获这些Error,因为捕获的意义不⼤,因为程序可能已经根本运⾏不了了。
  • Exception表示异常,表示程序出现Exception时,是可以靠程序⾃⼰来解决的,⽐如NullPointerException、IllegalAccessException等,我们可以捕获这些异常来做特殊处理。
  • Exception的⼦类通常⼜可以分为RuntimeException和⾮RuntimeException两类
  • RunTimeException表示运⾏期异常,表示这个异常是在代码运⾏过程中抛出的,这些异常是⾮检查异常,程序中可以选择捕获处理,也可以不处理。这些异常⼀般是由程序逻辑错误引起的,程序应该从逻辑⻆度尽可能避免这类异常的发⽣,⽐如NullPointerException、IndexOutOfBoundsException等。
  • ⾮RuntimeException表示⾮运⾏期异常,也就是我们常说的检查异常,是必须进⾏处理的异常,如果不处理,程序就不能检查异常通过。如IOException、SQLException等以及⽤户⾃定义的Exception异常。

在Java的异常处理机制中,什么时候应该抛出异常,什么时候捕获异常?

异常相当于⼀种提示,如果我们抛出异常,就相当于告诉上层⽅法,我抛了⼀个异常,我处理不了这个异常,交给你来处理,⽽对于上层⽅法来说,它也需要决定⾃⼰能不能处理这个异常,是否也需要交给它的上层。

所以我们在写⼀个⽅法时,我们需要考虑的就是,本⽅法能否合理的处理该异常,如果处理不了就继续向上抛出异常,包括本⽅法中在调⽤另外⼀个⽅法时,发现出现了异常,如果这个异常应该由⾃⼰来处理,那就捕获该异常并进⾏处理。

JVM

JVM中哪些是线程共享区

堆区和⽅法区是所有线程共享的,栈、本地⽅法栈、程序计数器是每个线程独有的

在这里插入图片描述

项⽬如何排查JVM问题

对于还在正常运⾏的系统:

  1. 可以使⽤jmap来查看JVM中各个区域的使⽤情况
  2. 可以通过jstack来查看线程的运⾏情况,⽐如哪些线程阻塞、是否出现了死锁
  3. 可以通过jstat命令来查看垃圾回收的情况,特别是fullgc,如果发现fullgc⽐较频繁,那么就得进⾏调优了
  4. 通过各个命令的结果,或者jvisualvm等⼯具来进⾏分析
  5. ⾸先,初步猜测频繁发送fullgc的原因,如果频繁发⽣fullgc但是⼜⼀直没有出现内存溢出,那么表示fullgc实际上是回收了很多对象了,所以这些对象最好能在younggc过程中就直接回收掉,避免这些对象进⼊到⽼年代,对于这种情况,就要考虑这些存活时间不⻓的对象是不是⽐较⼤,导致年轻代放不下,直接进⼊到了⽼年代,尝试加⼤年轻代的⼤⼩,如果改完之后,fullgc减少,则证明修改有效
  6. 同时,还可以找到占⽤CPU最多的线程,定位到具体的⽅法,优化这个⽅法的执⾏,看是否能避免某些对象的创建,从⽽节省内存

对于已经发⽣了OOM的系统:

  1. ⼀般⽣产系统中都会设置当系统发⽣了OOM时,⽣成当时的dump⽂件(-XX:+HeapDumpOnOutOfMemoryError -XX : HeapDumpPath = /usr/local/base)
  2. 我们可以利⽤jsisualvm等⼯具来分析dump⽂件
  3. 根据dump⽂件找到异常的实例对象,和异常的线程(占⽤CPU⾼),定位到具体的代码
  4. 然后再进⾏详细的分析和调试

总之,调优不是⼀蹴⽽就的,需要分析、推理、实践、总结、再分析,最终定位到具体的问题

⼀个对象从加载到JVM,再到被GC清除,都经历了什么过程?

  1. ⾸先把字节码⽂件内容加载到⽅法区
  2. 然后再根据类信息在堆区创建对象
  3. 对象⾸先会分配在堆区中年轻代的Eden区,经过⼀次Minor GC后,对象如果存活,就会进⼊Suvivor区。在后续的每次Minor GC中,如果对象⼀直存活,就会在Suvivor区来回拷⻉,每移动⼀次,年龄加1
  4. 当年龄超过15后,对象依然存活,对象就会进⼊⽼年代
  5. 如果经过Full GC,被标记为垃圾对象,那么就会被GC线程清理掉

怎么确定⼀个对象到底是不是垃圾?

  1. 引⽤计数算法: 这种⽅式是给堆内存当中的每个对象记录⼀个引⽤个数。引⽤个数为0的就认为是
    垃圾。这是早期JDK中使⽤的⽅式。引⽤计数⽆法解决循环引⽤的问题。
  2. 可达性算法: 这种⽅式是在内存中,从根对象向下⼀直找引⽤,找到的对象就不是垃圾,没找到的对象就是垃圾。

JVM有哪些垃圾回收算法?

  1. 标记清除算法
    a. 标记阶段:把垃圾内存标记出来
    b. 清除阶段:直接将垃圾内存回收。
    c. 这种算法是⽐较简单的,但是有个很严重的问题,就是会产⽣⼤量的内存碎⽚。
  2. 复制算法:为了解决标记清除算法的内存碎⽚问题,就产⽣了复制算法。复制算法将内存分为⼤⼩相等的两半,每次只使⽤其中⼀半。垃圾回收时,将当前这⼀块的存活对象全部拷⻉到另⼀半,然后当前这⼀半内存就可以直接清除。这种算法没有内存碎⽚,但是他的问题就在于浪费空间。⽽且,他的效率跟存活对象的个数有关。
  3. 标记压缩算法:为了解决复制算法的缺陷,就提出了标记压缩算法。这种算法在标记阶段跟标记清除算法是⼀样的,但是在完成标记之后,不是直接清理垃圾内存,⽽是将存活对象往⼀端移动,然后将边界以外的所有内存直接清除。

什么是STW?

STW: Stop-The-World,是在垃圾回收算法执⾏过程当中,需要将JVM内存冻结的⼀种状态。在STW状态下,JAVA的所有线程都是停⽌执⾏的-GC线程除外,native⽅法可以执⾏,但是,不能与JVM交互。GC各种算法优化的重点,就是减少STW,同时这也是JVM调优的重点。

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

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

相关文章

笔记本摄像头怎么打开?记牢这5个简单方法!

“我有一个紧急视频会议&#xff0c;但是关键时刻我的笔记本电脑摄像头居然打不开了&#xff0c;真的让我很崩溃。有什么方法可以快速解决这个问题吗&#xff1f;非常感谢&#xff01;” 在互联网时代&#xff0c;电脑对我们来说非常重要。而借助电脑摄像头与朋友交流或者与同事…

601-体育馆的人流量

文章目录 601-体育馆的人流量1. 题目2. 思路3. 解决4. 运行结果 601-体育馆的人流量 1. 题目 2. 思路 思路&#xff1a;查询Stadium表中人流量超过100的记录&#xff0c;将查询结果与自身的临时表连接&#xff0c;再使用where获得满足条件的记录 查询Stadium表中人流量超过10…

asp.net服装管理系统三层架构

asp.net服装管理系统三层架构说明文档 运行前附加数据库.mdf&#xff08;或sql生成数据库&#xff09; 主要技术&#xff1a; 基于asp.net架构和sql server数据库&#xff0c;并采用EF实体模型开发。 三层架构并采用EF实体模型开发 功能模块&#xff1a; 运行环境&#xff1…

CyclicBarrier 、CountDownLatch 、Semaphore 的用法

1 CountDownLatch&#xff08;线程计数器 &#xff09; CountDownLatch类位于java.util.concurrent 包下&#xff0c;利用它可以实现类似计数器的功能。比如有一个任务 A&#xff0c;它要等待其他 4 个任务执行完毕之后才能执行&#xff0c;此时就可以利用 CountDownLatch 来实…

第二证券:国庆档票房有望延续复苏态势 海风拐点已至

昨日&#xff0c;两市股指盘中强势轰动上扬&#xff0c;创业板指早盘一度涨近2%&#xff0c;随后涨幅逐渐收窄。到收盘&#xff0c;沪指涨0.16%报3107.32点&#xff0c;深成指涨0.44%报10104.32点&#xff0c;创业板指涨0.82%报2006.22点&#xff0c;两市算计成交7165亿元&…

iOS 视频压缩 mov转mp4 码率

最近还是因为IM模块的功能&#xff0c;IOS录制MOV视频发送后&#xff0c;安卓端无法播放&#xff0c;迫不得已兼容将MOV视频转为MP4发送。 其中mov视频包括4K/24FPS、4K/30FPS、4K/60FPS、720p HD/30FPS、1080p HD/30FPS、1080p HD/60FPS&#xff01; 使用AVAssetExportSessi…

排序学习总结

取每个对象的内接矩形框&#xff0c;然后再排序&#xff0c;根据排序的结果确定原对象顺序。 inner_rectangle1(RegionAffineTrans1, Row1, Column1, Row2, Column2) gen_rectangle1(Rect,Row1, Column1, Row2, Column2) sort_region(Rect,RectSort,character,true, row)count…

4k、VR与万兆光网

“全光万兆”对VR意义重大。 pico4的分辨率 PICO 4 的单眼分辨率是 2160 2160&#xff0c;整体分辨率高达 4320 2160。这是一款高性能的 VR 一体机&#xff0c;采用了 2.56 英寸的 Fast-LCD 屏幕&#xff0c;最高可实现 90Hz 刷新率&#xff0c;还有 1200 PPI 和 20.6 PPD 的…

一、2023.9.27.C++基础.1

回答问题一定要有逻辑性&#xff0c;我将从 这个技术是什么&#xff1f; 为什么要有这个技术&#xff1f; 这个技术底层是怎么实现的&#xff1f; 这个技术的优点缺点&#xff1f; 这个技术所适合的使用场景&#xff1f; 以下五个方面来回答问题。 文章目录 一、C基础部分&…

行为型设计模式——责任链模式

摘要 责任链模式(Chain of responsibility pattern): 通过责任链模式, 你可以为某个请求创建一个对象链. 每个对象依序检查此请求并对其进行处理或者将它传给链中的下一个对象。 一、责任链模式意图 职责链模式&#xff08;Chain Of Responsibility&#xff09; 是一种行为设…

弱信号的采样与频谱分析(修订中...)

1.频谱混叠效应 - 波形数据抽样 这是一组经过抽样的数据的频谱&#xff0c;红圈圈出的两条谱线&#xff0c;是我们需要关注的特征谱线。这个信号与右侧的临近信号比较&#xff0c;求频率比值&#xff0c;比值恒定与理论推导相符。再5取1降低采样率后&#xff0c;大致相同的频率…

接口测试--Postman常用断言

Postman的断言是用javascript语言写的 引入--什么是断言 结果中的特定属性或值与预期做对比&#xff0c;如果一致&#xff0c;则用例通过&#xff0c;如果不一致&#xff0c;断言失败&#xff0c;用例失败。断言&#xff0c;是一个完整测试用例所不可或缺的一部分&#xff0c…

Linux系统上使用SQLite

1. 安装SQLite 在Linux上安装SQLite非常简单。可以使用包管理器&#xff08;如apt、yum&#xff09;直接从官方软件源安装SQLite。例如&#xff0c;在Ubuntu上使用以下命令安装SQLite&#xff1a; sudo apt-get install sqlite32. 打开或创建数据库 要打开或创建一个SQLite数…

5月22日比特币披萨日,今天你吃披萨了吗?

比特币披萨日 1. Laszlo Hanyecz2. 最贵披萨诞生记3. 梭哈买披萨4. 未完待续 2010年5月22日&#xff0c;美国佛罗里达州的程序员Laszlo Hanyecz&#xff08;拉兹洛哈涅克斯&#xff09;用10000个比特币购买了棒约翰&#xff08;Papa Johns&#xff09;比萨店一个价值25美元的奶…

什么人适合学NPDP产品经理认证?

NPDP产品经理认证&#xff0c;最适合学的就是产品经理了&#xff0c;但是证书没有局限性&#xff0c;适用于所有与产品开发相关的行业和领域&#xff0c;特别是那些需要提高产品成功率和效率的团队成员。就是一句话&#xff0c;只要你觉得有用&#xff0c;都可以考。 通过学习N…

Softing物联网(IoT)方案之OT/IT数据集成

一 利用数据提高效率和绩效 多年以来数据集成和工业物联网一直在推动着市场的发展&#xff0c;目前我们已经能够集成并成功使用先进的技术、大量的传感器和复杂的数据格式等。而在工业物联网或工业4.0中&#xff0c;还有运营技术&#xff08;OT&#xff09;和信息技术&#xf…

Video Caption / 视频字幕:常用指标(BELU-4,ROUGE-L,METEOR,CIDEr,SPICE)和数据集总结

本文作为入门Video Caption / 视频字幕 的随笔记录&#xff0c;用于查漏补缺和回顾&#xff0c;难免有疏漏和不足指出&#xff0c;烦请指出&#xff01; 一、指标 Video Caption / 视频字幕常用的标准指标有四种&#xff1a;BLEU-1[1]&#xff0c;BLEU-2[1]&#xff0c;BLEU-3[…

LeetCode算法二叉树—LCR 194. 二叉树的最近公共祖先

目录 LCR 194. 二叉树的最近公共祖先 - 力扣&#xff08;LeetCode&#xff09; 代码&#xff1a; 运行结果&#xff1a; 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个结点 p、q&#xff0c;最…

realloc函数应用IO泄露体验

本题主要介绍realloc函数&#xff0c;平时我们使用realloc最多便是在打malloc_hook–>onegadget的时候&#xff0c;使用realloc_hook调整onegadget的栈帧&#xff0c;从而getshell。 在realloc函数中&#xff0c;也能像malloc一样创建堆&#xff0c;并且比malloc麻烦一些&a…

计算机,软件工程,网络工程,大数据专业毕业设计选题有哪些(附源码获取)

计算机&#xff0c;软件工程&#xff0c;网络工程&#xff0c;大数据专业毕业设计选题有哪些?&#xff08;附源码获取&#xff09; ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于J…