陈川点滴

JAVA面试汇总

现在总结一下关于java面试的一些面试问题。
找了很久,找到一个前辈总结的面试精华传统IT转互联网面试经验分享。同时,强烈推荐海子- Java并发编程
先写一下今天遇到的一道算法面试题,题目如下:
给定一个存放整数的数组,重新排列数组使得数组左边为奇数,右边为偶数。要求:空间复杂度O(1),时间复杂度为O(n)
伪代码如下,左右开弓,完美解决~:

m = 0
n= 1en-1  
while i< len-1 && m <= n:
    if array[m] 偶数 &&  array[n] 偶数:
        n = len-1-i
    else  if array[m] 奇数 && array[n] 奇数:
        m = i+1
    else if m 奇数 && n偶数:
        i++
        m = i
        n = array[len-1-i]
    else if m 偶数 &&  n 奇数:
        exchange array[m] array[n]
        i++
        m = i
        n  = array[len-1-i]  

java关键字

作用域关键字

关键字 类内部 本包 子类 外部包
public
protectedl-scale ×
default × ×
private × × ×
  • 对于public修饰符,它具有最大的访问权限,可以访问任何一个在CLASSPATH下的类、接口、异常等。它往往用于对外的情况,也就是对象或类对外的一种接口的形式。
  • 对于protected修饰符,它主要的作用就是用来保护子类的。它的含义在于子类可以用它修饰的成员,其他的不可以,它相当于传递给子类的一种继承的东西。
  • 对于default来说,有点的时候也成为friendly(友员),它是针对本包访问而设计的,任何处于本包下的类、接口、异常等,都可以相互访问,即使是父类没有用protected修饰的成员也可以。
  • 对于private来说,它的访问权限仅限于类的内部,是一种封装的体现,例如,大多数的成员变量都是修饰符为private的,它们不希望被其他任何外部的类访问。

注意:Java的访问控制是停留在编译层的,也就是它不会在.class文件中留下任何的痕迹,只在编译的时候进行访问控制的检查。其实,通过反射的手段,是可以访问任何包下任何类中的成员,例如,访问类的私有成员也是可能的。从中可以扩展两个标题,即java的生命周期java类反射
区别

  1. public:可以被所有其他类所访问。
  2. private:只能被自己访问和修改。
  3. protected:自身,子类及同一个包中类可以访问。
  4. default(默认):同一包中的类可以访问,声明时没有加修饰符,认为是friendly。

static|final关键字

  • static可以用来修饰类的成员方法、类的成员变量,另外可以编写static代码块来优化程序性能,不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问。Java中的static关键字解析
  • final关键字可以用来修饰类、方法和变量(包括成员变量和局部变量)。
    当用final修饰一个类时,表明这个类不能被继承。String的定义
    public final class String {}
    
    String的值是可改变的,其实是String的地址是没有改变,但是指针的位置发生改变。初探Java字符串
  • final修饰变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。浅析Java中的final关键字

    synchronized|volatile关键字

  • synchronized用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。Java并发编程:synchronized

注意

  1. 当一个线程正在访问一个对象的synchronized方法,那么其他线程不能访问该对象的其他synchronized方法。这个原因很简单,因为一个对象只有一把锁,当一个线程获取了该对象的锁之后,其他线程无法获取该对象的锁,所以无法访问该对象的其他synchronized方法。
  2. 当一个线程正在访问一个对象的synchronized方法,那么其他线程能访问该对象的非synchronized方法。这个原因很简单,访问非synchronized方法不需要获得该对象的锁,假如一个方法没用synchronized关键字修饰,说明它不会使用到临界资源,那么其他线程是可以访问这个方法的。
  3. 如果一个线程A需要访问对象object1的synchronized方法fun1,另外一个线程B需要访问对象object2的synchronized方法fun1,即使object1和object2是同一类型),也不会产生线程安全问题,因为他们访问的是不同的对象,所以不存在互斥问题。
  4. 并且如果一个线程执行一个对象的非static synchronized方法,另外一个线程需要执行这个对象所属类的static synchronized方法,此时不会发生互斥现象,因为访问static synchronized方法占用的是类锁,而访问非static synchronized方法占用的是对象锁,所以不存在互斥现象。
  • volatile关键字是与Java的内存模型有关。编译器为了加快程序运行的速度,对一些变量的写操作会先在寄存器或者是CPU缓存上进行,最后才写入内存.而在这个过程,变量的新值对其他线程是不可见的.而volatile的作用就是使它修饰的变量的读写操作都必须在内存中进行。Java并发编程:volatile关键字解析
  • volatile与synchronized
  1. volatile本质是在告诉jvm当前变量在寄存器中的值是不确定的,需要从主存中读取,synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住.
  2. volatile仅能使用在变量级别,synchronized则可以使用在变量,方法.
  3. volatile仅能实现变量的修改可见性,但不具备原子特性,而synchronized则可以保证变量的修改可见性和原子性.
  4. volatile不会造成线程的阻塞,而synchronized可能会造成线程的阻塞.
  5. volatile标记的变量不会被编译器优化,而synchronized标记的变量可以被编译器优化.

    java对象

    java数据结构

    java多线程

陈川 wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!

热评文章