1. 面向对象和面向过程的区别?
    面向过程比面向对象的性能更好,因为面向对象需要对类进行实例化操作,开销比较大,比较消耗资源。但面向对象的优点是 易扩展,易复用,易维护。面向对象包含特性有封装、继承、多态。可以设计出更加低耦合的系统。
    关于性能的比较并不是因为Java面向过程的性能低,面向过程本身也需要分配内存、计算内存偏移量是因为Java本身是半编译解释性语言,Java编译后生成的是字节码,并不能被CPU直接识别的机器码。
  2. Java和C++的区别有哪些?
  • Java和C++在继承方面:Java不支持多重类继承;C++可以多继承。
  • Java的反射特性;
  • Java没有指针的概念;
  • Java的内存管理和垃圾回收机制;
  • Java不支持操作符重载,而C++操作符重载是其突出的特征;
  • Java除基本的数据类型外,其他都是对象型数据。
  • Java没有预处理器,通过import方式实现预处理;C++有预处理阶段,但增加了编译复杂性。
  • Java不支持缺省的函数参数;C++支持;
  • 待补充...
  1. JVM介绍
    JVM(Java virtual machine) java的虚拟机,其在windows、linxu以及macos上都有其不同的实现,目的就是使用相同的字节码给出相同结果。
    字节码就是Java编译生成的.class文件,只面向虚拟机。
    image.png
    在字节码转换为机器码的过程中,在这一步JVM类加载器加载字节码文件并通过解释器逐行解释运行,这种方式比较慢,且由于部分代码频繁被调用(热点代码),所以后来引进了JIT运行时编译器。其会优化的热点字节码转换的机器码保存起来,方便下次直接调用。JAVA是编译和解释共同存的语言;
    Java程序最初是通过解释器(Interpreter)进行解释执行的,当虚拟机发现某个方法或代码块的运行特别频繁时,就会把这些代码认定为“_热点代码_”。为了提高热点代码的执行效率,在运行时,虚拟机将会把这些代码编译成与本地平台相关的机器码,并进行各种层次的优化,完成这个任务的编译器称为_即时编译器_(Just In Time Compiler,下文统称JIT编译器)。

image.png
参考:https://blog.csdn.net/qq_4170...

  1. 重载和重写的区别是
    重载是在同一类内,方法名必须相同,参数类型、参数个数及顺序不同;方法返回值或修饰符可以不同。
    重写是发生在子类对父类的允许访问的方法的实现过程进行重写,发生在子类中,方法名和参数列表必须相同,返回值范围需小于父类,抛出异常范围小于父类,访问修饰符范围大等于父类。如果父类方法访问修饰符为private,则子类不能重写该方法。
  2. 面向对象的三大特性
    封装:把一个对象私有化,同时提供一些可以被外界访问的属性的方法。
    继承:使用已经存在的类的定义的基础上建立新的类,新的类可以定义新的功能,也可以使用父类的功能。(1)子类继承父类所有的属性和方法,但父类的私有方法和属性无法访问,只是拥有。(2)子类拥有自己的属性和方法。(3)子类可以重写父类的方法。
    多态:对于对象的引用变量具体只向的是哪一个实例对象,需要程序运行时决定。父类可以只向不同的子类对象。多态的实现方式:继承重写和接口覆盖。
  3. String、StringBuilder和StringBuffer的区别?
    String对象一旦创建就不可被改变,内部是final 定义的数组;
    StringBuilder 非线程安全;
    StringBuffer 线程安全,对方法加了同步锁;
    StringBuilder和StringBuffer都继承AbstractStringBuilder类,其对象都可以被改变
  4. 自动拆箱和装箱
    装箱:将基本类型用它们对应的引用类型包装起来;
    拆箱:将包装类型转换为基本数据类型。
    对于确定范围的基本数据类型(Integer,Long,Boolean)等有基本数据对象缓存(-128~128),如果两个不同的对象值范围在缓存范围内,两个对象相等,否则不等。
  5. 在一个静态方法内调用一个非静态成员为什么是非法的?

    因为静态方法是数据当前类的,而不是某一个对象,所以在对象未实例化时,不存在非静态成员。
    
  6. 对象实例和对象引用有什么区别?
    对象实例是存在放堆内存中,对象引用只向的是对象实例,存放在栈内存中中,一个对象实例可以被多个引用只向。对象的相等比的是它们存放的内容是否相等,引用相等比的是它们只向内存的地址是否相等。
    == 是比较两个对象的地址是否相同。
    equal()是判断两个对象是否相等。(1)如果类equal()没有被覆盖,则与==等价(2)如果类覆盖equals(),则用于判断两个对象内容是否相等。
  7. List,Set和Map的区别?

    List存储一组不唯一的有序的对象;Set不允许重复的集合;Map使用key-value键值对存储,key不能重复
    
  8. ArrayList和LinkList的区别?
    都不是同步的;ArrayList是一个Object数组,LinkList是一个双向链表;
  9. ArrayList的扩容机制?
    ArrayList默认构造size为10,每次扩容是原来容量的1.5倍。
  10. HashMap和HashTable的区别?
    (1) 线程安全:HashMap是非线程安全,HashTable是线程安全的。线程安全建议使用ConcurrentHashMap
    (2)HashMap效率高于HashTable,目前HashTable已经被淘汰,不建议使用;
    (3)HashMap中null可以当主键,但仅能有一个,HashTable键值不能为null;
    (4)HashTable默认容量11,之后每次扩容容量变为2n+1;HastMap默认容量为16,之后每次扩容,容量为原来的2倍,即总是使用2的幂作为哈希表的大小;
    (5)HashMap底层数据结构为哈希数据加链表,当链表长度大于阈值8时,链表转换为红黑树,以减少搜索时间;链表是为了解决哈希冲突而存在的,即拉链法解决冲突;红黑树为了减少搜素时间。
  11. 进程和线程的区别?
    进程是程序执行的最基本单元,进程是动态的,系统运行一个程序即是从一个进程创建,运行到消亡的过程。启动main函数就是启动了一个jvm的进程,而main所在的线程是主线程。线程是比进程更小的执行单元。一个进程可以产生多个线程。线程共享进程的堆和方法区资源,但每个线程都有自己的程序计数器、虚拟机栈和本地方法栈。
    字节码解释器通过改变程序计数器来实现代码的流程控制,如顺序执行、选择、循环、异常处理。在多线程的情况下,程序计数器用于记录线程当前的执行位置,从而完成上下文切换。虚拟机栈在每个java方法在执行的同时创建一个栈桢用于存储局部变量表、操作数栈、常量池引用等信息。从方法调用到完成,就对应一个栈桢在Java虚拟机中入栈和出栈的过程。 堆和方法区所线程共享的资源,堆用于存储新创建的对象,方法区用于存储已被加载的类信息、常量、静态变量和即时编译器编译后的代码等数据。
  12. 并行和并发的区别?
    并行是在单位时间内,多个任务的执行;
    并发是在同一时间段,多个任务同时执行。
  13. 死锁?
    死锁是指多个线程同时被阻塞,它们中的一个或全部都在等待某一个资源的释放。
    死锁的四个必要条件:(1)互斥条件,资源的互斥;(2)请求与保持,线程因请求资源而阻塞,对已获得的资源保持不放(3)不可剥夺,线程已获得的资源在未使用完前不能被强行剥夺,只有自己使用完后才释放;(4)循环等待,线程之间形成头尾相接的循环等待资源关系。
  14. sleep和wait的区别?
    sleep方法没有释放锁,wait方式释放了锁;
    两者都可以暂停线程的执行;
    wait通常用于线程间交互通信,sleep用于暂停执行;
    wait方法被调用后,线程不会自动苏醒,需要通过notify或者nitifyall方法。sleep后会自动苏醒;wait(long timeout)可以超时后苏醒。
  15. synchronized 关键字?
    synchronized 关键字解决线程间资源访问的同步性,早起它是一个重量级的锁。锁主要存在四种状态,依次是无锁,偏向锁,轻量级锁和重量级锁。他们会随着竞争的激烈而逐渐升级。锁的升级不可降级。
  16. synchronized和reentrantlock的区别
    两者都是可重入锁,即同一线程可再次获取锁,通过锁计数器实现。synchronized是jvm实现,reentrantlock是api实现。前者智能是非公平锁,后者可以指定是公平锁或者非公平锁。 所谓的公平锁即谁先等待的线程先获得锁。
  17. volatile关键字
    java的内存模型下,线程可以将变量保存在本地内存(比如寄存器),这就会导致如果一个线程在主内存中修改了一个变量的值,而另一个线程还在使用它寄存器的变量值的拷贝,会造成数据的不一致。工作内存和主内存的数据不一致。volatile是保证变量的可见性,同时可以防止指令重排。
    线程的三大特性:
    原子性:一个操作或者多次操作,要么全部得到执行并且不会收到任何因素干扰,要么所有操作都不执行。synchronized可以保证代码的原子性。
    可见性:一个变量多共享变量进行了修改,其他线程可以立即看到修改后的最新值。
    有序性:代码在执行过程中的先后顺序,java在编译和运行期间,代码的执行顺序未必与编写的代码时序一样。volatile可以保证禁止指令进行重新排序优化。
  18. synchronized和volatile的比较
    volatile是线程同步的轻量级实现性能比synchronized好,但其只能作用于变量,而synchronized可以作用于方法和代码块。
    volatile不会发生阻塞,主要用于解决变量在线程的可见性,synchronized用于线程间资源的访问同步性。
  19. java内存区域分布

image.pngimage.png

线程私有的:
程序计数器:用于记录程序执行字节码的行号指示器,在上下文切换后程序恢复到正确的位置。
虚拟机栈:虚拟机栈是由栈桢组成,每一个栈桢都拥有:局部变量表、操作数栈、动态链接和方法出口信息。虚拟机栈会抛出两种异常:StackOverFlowError指虚拟机栈内存不允许动态链接扩展,请求栈深度超过虚拟机栈深度最大的时候会抛出;OutOfMemoryError指栈内存允许扩展但内存不足。
本地方法区:本地方法栈为虚拟机使用到Native方法服务。

堆是线程共享的内存区域,目的是存放实例,几乎所有的对象实例以及数组都在这里分配内存,细分为新生代和老年代。主要包括四个区:eden,S0,S1和tentired。大部分情况,对象会首先在eden区域分配,然后在一次新生代垃圾回收后,如果对象还存活,则会进入s0或者s1,并且对象的年龄还会加1,当年龄加到一定程度后(默认15岁),被晋升为老年代。

  1. Java对象创建的过程
    类加载检查-》分配内存-》初始化零值-》设置对象头-》执行init方法
    image.png
    (1)类加载检查:new时,jvm会检查这个指令的参数是否能在常量池定位到这个累的符号引用,并且检查这个符号代表的类是否已被加载过、解析和初始化过。如果没有则需要执行类加载过程。
    (2)在类加载检查完毕后,对象所需的内存大小便可确定,分配内存。分配方式有“指针碰撞”和“空闲列表”,由java堆是否规整决定。
    JAVA的堆是否规整取决于gc收集器算法用的是标记-整理还是标记清除。
    image.png
    (3)初始化零值,内存分配完后,虚拟机将分配到的内存空间初始化为零值(不包括对象头),可保证java实例不赋初始值就直接使用。
    (4)设置对象头,初始化零值后,虚拟机对对象进行必要的设置,比如这个对象属于哪个类,元数据信息,对象的哈希码、gc分代年龄或者是否启用偏向锁等。
    (5)执行init方法,安装程序员的意思执行初始化工作。
  2. MinorGc和FullGc的不同
    MinorGc发生在Eden区域,通常对象的创建发生在eden区域,当eden区域内存不足时,虚拟机会触发一次MinorGc,MinorGc非常频繁,回收速度很快。FullGc发生在老年代,速度比MinorGc慢10倍以上。
  3. 如何判断对象是否死亡
    1 引用计数器,对每个对象添加一个引用计数器,每当有一个地方引用,计数器就加1;当引用失效,计数器就减1;任何时候计数器为0的对象就不可能再被使用。
    2 可达性分析法,基本思想是通过一系列的称为“GC Roots”的对象作为起点,从这些节点开始向下搜索,节点所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连的话,则证明此对象是不可用的。
  4. TCP是如何保证可靠传输的
    1 应用数据在会被分割成tcp认为最合适的发送数据块,MTU
    2 TCP会对每一个数据包进行编号,接收对收到的数据包进行排序,有序数据传给应用层。
    3 校验和,TCP会保证数据校验和,防止数据传输发生变化;
    4 TCP会丢弃重复的数据
    5 流量控制,滑动窗口算法,接收端只允许发送端发送接收缓冲区可以容纳的数据量大小,如果接收端来不及处理数据,会提示发送发降低发送速率,防止包丢失。
    6 拥塞控制,当网络拥塞时,减少数据的发送
    7 ARQ协议,没发送完一个分组后就停止发送,等待对方确认后再继续发送
    8 超时放,每发送完后就会启动定时器,确认是否收到目的方的确认,否则重发报文段。
  5. Spring事务隔离级别
    TransactionDefinition.ISOLATION_DEFAULT: 使用后端数据库默认的隔离级别;
    TransactionDefinition.ISOLATION_READ_UNCOMMITED: 最低隔离级别,允许获取未提交的事务的数据变更,可能会导致幻读、脏读或不可重复读。
    TransactionDefinition.ISOLATION_READ_COMMITTED: 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读和不可重复读仍有可能发生。
    TransactionDefinition.ISOLATION_REPEATABLE_READ: 对同一字段多次读取结果是一样的,除非事务修改,但仍有幻读的可能性。
    TransactionDefinition.ISOLATION_SERIALIZABLE: 严格服从ACID。

(附加信息) 脏读:A事务在更新数据后未提交,B事物看到了未提交的更新数据,结果A事务回滚,此时B事务在此之前所看到的数据为"脏数据";
不可重复读:同一事务在更新数据前两次读取数据的结果不一致。A事务在B事务更新操作前读取了一次数据,更新操作之后又读取了一次数据,两次读取的数据结果不一致。 通常发生在不同事务的数据修改。
幻读:同一事务内多次查询的结果不一致。新增或者删除 (数据条数变化)

  1. Spring 事务的传播性
    TransactionDefinition.PROPAGATION_REQUIRED: 如果当前存在事务,则加入到该事务,否则创建新我hi物;
    TransactionDefinition.PROPAGATION_SUPPORT:如果单前 存在事务,则加入事务,否则以非事务方式运行;
    TransactionDefinition.PROPAGATION_MANDATORY: 如果当前存在事务,则加入事务,否则抛出异常。 mandatory 强制性
    TransactionDefinition.PROPAGATION_REQUIRES_NEW: 创建一个新事务,如果当前存在事务,则挂起该事务;
    TransactionDefinition.PROPAGATION_NOT_SUPPORT: 以非事务方式运行,如果当前存在事务则挂起该事务;
    TransactionDefinition.PROPAGATION_NEVER: 以非事务方式运行;
    TransactionDefinition.NESTED: 如果当前存在事务,则创建一个事务作为当前事务嵌套事务运行;如果当前没有事务,则等价于 TransactionDefinition.PROPAGATION_REQUIRED。

dqiang
0 声望0 粉丝