JAVA简答(一)

  1. 为什么Java被称作是“平台无关的编程语言”?
    java源程序先经过javac编译器编译成二进制的.class字节码文件,.class文件再运行在jvm上,java解释器(jvm的一部分)会将其解释成对应平台的机器码执行。所以java所谓的跨平台就是在不同平台上安装了不同的jvm,而在不同平台上生成的.class文件都是一样的。

  2. 是否可以在static环境中访问非static变量?
    Static表示静态的意思,可用于修饰成员变量和成员函数。因为静态的成员属于类,随着类的加载而加载到静态方法区内存,当类加载时,此时不一定有实例创建,没有实例,就不可以访问非静态的成员。同理,Java中static方法不能被覆盖,因为方法覆盖是基于运行时动态绑定的。

  3. Java支持的数据类型有哪些?什么是自动拆装箱?
    Java支持的数据类型包括两种

  • 基本数据类型:包含byte,char,short, boolean ,int , long, float,double
  • 引用类型:如String等,JVM中虚拟栈中存的是对象的地址,创建的对象实质在堆中,通过地址来找到堆中的对象的过程,即为引用类型。

自动装箱就是Java编译器在基本数据类型和对应的对象包装类型间的转化,即int转化为Integer,自动拆箱是Integer调用其方法将其转化为int的过程。

  1. Java中的方法重写和方法重载是什么意思?
    方法重写的原则:
  • 重写方法的方法名称、参数列表必须与原方法的相同,返回类型可以相同也可以是原类型的子类型(从Java SE5开始支持)。
  • 重写方法不能比原方法访问性差(即访问权限不允许缩小)。
  • 重写方法不能比原方法抛出更多的异常。
  • 被重写的方法不能是final、private和static。
  • 重写是发生在运行时的,因为编译期编译器不知道并且没办法确定该去调用哪个方法,JVM会在代码运行的时候作出决定。

方法重载的原则:

  • 方法名称必须相同。
  • 参数列表必须不同(个数不同、或类型不同、参数类型排列顺序不同等)。
  • 方法的返回类型可以相同也可以不相同,仅仅返回类型不同不足以成为方法的重载。
  • 重载是发生在编译时的,因为编译器可以根据参数的类型来选择使用哪个方法。

重写和重载的不同:

  • 方法重写要求参数列表必须一致,而方法重载要求参数列表必须不一致。
  • 方法重写要求返回类型必须一致(或为其子类型),方法重载对此没有要求。
  • 方法重写只能用于子类重写父类的方法,方法重载用于同一个类中的所有方法。
  • 方法重写对方法的访问权限和抛出的异常有特殊的要求,而方法重载在这方面没有任何限制。
  • 父类的一个方法只能被子类重写一次,而一个方法可以在所有的类中可以被重载多次。
  1. 接口和抽象类的区别是什么?
    不同点在于:
  • 接口中所有的方法隐含的都是抽象的。而抽象类则可以同时包含抽象和非抽象的方法。
  • 类可以实现很多个接口,但是只能继承一个抽象类
  • 类可以不实现抽象类和接口声明的所有方法,当然,在这种情况下,类也必须得声明成是抽象的。
  • 抽象类可以在不提供接口方法实现的情况下实现接口。
  • Java接口中声明的变量默认都是final的。抽象类可以包含非final的变量。
  • Java接口中的成员函数默认是public的。抽象类的成员函数可以是private,protected或者是public。

从设计层面来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。

  1. 值传递和引用传递?
    参见《Head first JAVA》的杯子和遥控器模型。

  2. 进程和线程的区别是什么?

  • 进程是运行中的程序,线程是进程的内部的一个执行序列
  • 进程是资源分配的单元,线程是执行行单元
  • 进程间切换代价大,线程间切换代价小
  • 进程拥有资源多,线程拥有资源少
  • 多个线程共享进程的资源,进程间地址和资源独立

守护线程:服务线程,是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程,并且这种线程并不属于程序中不可或缺的部分。当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。

  1. 创建线程有几种不同的方式?
    创建方式:
  • 继承Thread类(真正意义上的线程类),是Runnable接口的实现。
  • 实现Runnable接口,并重写里面的run方法。
  • 使用Executor框架创建线程池。Executor框架是juc里提供的线程池的实现。

Thread类的常见方法参见:创建线程有几种不同的方式?

  1. 线程的几种可用状态
  • 新建( new ):新创建了一个线程对象。
  • 就绪状态( runnable ):线程对象创建后,其他线程调用了该对象的 start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中获 取 cpu 的使用权。
  • 运行( running ):已就绪的线程获得了 cpu 时间片( timeslice ),执行程序代码。
  • 阻塞( block ):阻塞状态是指线程因为某种原因放弃了 cpu 使用权,暂时停止运行。阻塞的情况分三种:
    (一). 等待阻塞:运行的线程执行 o.wait ()方法, JVM 会把该线程放 入等待队列中。
    (二). 同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则 JVM 会把该线程放入锁池中。
    (三). 其他阻塞: 运行的线程执行 Thread.sleep ( long ms )或 t.join ()方法,或者发出了 I / O 请求时, JVM 会把该线程置为阻塞状态。
  • 死亡( dead ):线程 run ()、 main () 方法执行结束,或者因异常退出了 run ()方法,则该线程结束生命周期。死亡的线程不可再次复生。
image
  1. 如何确保N个线程可以访问N个资源同时又不导致死锁?
    死锁是指多个进程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进。多线程产生死锁的四个必要条件:
  • 互斥条件:一个资源每次只能被一个进程使用。
  • 保持和请求条件:一个进程因请求资源而阻塞时,对已获得资源保持不放。
  • 不可剥夺:进程已获得资源,在未使用完成前,不能被剥夺。
  • 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

只要破坏其中任意一个条件,就可以避免死锁,其中最简单的就是破环循环等待条件。按同一顺序访问对象,加载锁,释放锁。

  1. 线程池是什么?
  • 创建线程池的方式
    newFixedThreadPool(int nThreads):创建固定长度线程池,每当提交一个任务就创建一个线程,直到达到线程池的最大数量。
    newCachedThreadPool():创建一个可缓存的线程池,线程池的规模不存在任何限制。如果线程池的规模超过了处理需求,将自动回收空闲线程,而当需求增加时,则可以自动添加新线程。
    newSingleThreadExecutor():创建单个工作线程来执行任务,特点是能依照任务在队列中的顺序来串行执行。
    newScheduledThreadPool(int corePoolSize):创建固定长度线程池,而且以延迟或定时的方式来执行任务,类似于Timer。

  • 线程池状态
    线程池的5种状态:RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED。
    RUNNING:线程池一旦被创建,就处于 RUNNING 状态,任务数为 0,能够接收新任务,对已排队的任务进行处理。
    SHUTDOWN:不接收新任务,但能处理已排队的任务。
    STOP:不接收新任务,不处理已排队的任务,并且会中断正在处理的任务。
    TIDYING:SHUTDOWN 或STOP状态下,任务数为 0, 其他所有任务已终止,线程池会变为 TIDYING 状态。
    TERMINATED:线程池在 TIDYING 状态执行完 terminated() 方法就会彻底终止。

    状态转换图

  • 线程池中 submit()execute()
    二者都是用于提交任务,区别在于
    ①接收参数:execute()方法只能接收实现Runnable接口类型的任务;submit()方法则既可以接收RunnableCallable类型的任务。
    ②返回值:execute()的返回值是voidsubmit()的返回值是Future,通过.get()方法可以获取到线程执行的返回值。
    ③异常的处理:execute()执行Runnable的任务时,run()方法有显式的抛出异常。

  1. 同步方法和同步代码块的区别是什么?
  • 同步的意义
    java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(增删改查),将会导致数据的不准确,相互之间产生冲突。因此加入了同步锁,以避免在该线程没有结束前,调用其他线程。从而保证了变量的唯一性,准确性。

  • 同步的实现:在 java 虚拟机中, 每个监视器和一个对象引用相关联, 每个对象都关联着一把锁。如果使用关键字synchronized修饰方法的方法或者代码块,那么这个部分将获取内置锁,放入了监视器的监视区域, 确保只有当前线程可以访问该变量,其他线程被阻塞住。

  • 注意:
    (一). 同步方法默认用this或者当前类class对象作为锁。
    (二). 若同步静态方法,调用过程,将锁住整个类。
    (三). 同步代码块可以选择以什么来加锁,比同步方法要更颗粒化

  1. 怎么保证多线程的运行安全
  • 线程安全在三个方面体现
    ① 原子性:提供互斥访问,同一时刻只能有一个线程对数据进行操作(atomic, synchronized);
    ② 可见性:一个线程对主内存的修改可以及时地被其他线程看到(synchronized, volatile);
    ③ 有序性:一个线程观察其他线程中的指令执行顺序,由于指令重排序,该观察结果一般杂乱无序(happens-before原则)。
  • ThreadLocal实现线程安全
    ThreadLocal类来支持线程局部变量,线程局部变量是局限于线程内部的变量,属于线程自身所有,不在多个线程间共享。任何线程局部变量一旦在工作完成后没有释放,Java 应用就存在内存泄露的风险。
  1. synchronized、volatile、Lock、ReentrantLock、atomic
  • synchronizedvolatile区别
    ① volatile仅有可见性,不能保证原子性;synchronized具有可见性和原子性
    ② volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类。
    ③ volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。
    ④ volatile标记的变量不会被编译器优化;synchronized标记的可以被优化
  • synchronizedLock 区别
    ① synchronized是java内置关键字,在jvm层面,Lock是个java类
    ② synchronized无法判断是否获取锁的状态,Lock可以判断是否获取到锁;
    ③ synchronized会自动释放锁,Lock需在finally中手工释放锁;
    ④ synchronized如果阻塞会一直保持等待,而Lock如果尝试获取不到锁,线程可以不用一直等待就结束;
    ⑤ synchronized的锁可重入、不可中断、非公平,而Lock锁可重入、可判断、可公平(两者皆可);
    ⑥ Lock锁适合大量同步的代码,synchronized锁适合代码少量的同步问题。
  • synchronizedReentrantLock 区别
    二者的本质区别在于synchronized是关键字,ReentrantLock是类,因此ReentrantLock提供了更多更灵活的特性,可以被继承、可以有方法、可以有各种各样的类变量。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,252评论 6 516
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,886评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,814评论 0 361
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,869评论 1 299
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,888评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,475评论 1 312
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,010评论 3 422
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,924评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,469评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,552评论 3 342
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,680评论 1 353
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,362评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,037评论 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,519评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,621评论 1 274
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,099评论 3 378
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,691评论 2 361

推荐阅读更多精彩内容

  • 15 . Java集合类框架的基本接口有哪些? 什么是迭代器(Iterator)? 定义:迭代器是一种设计模式,它...
    大脸猫猫脸大阅读 207评论 0 0
  • 1.八种基本数据类型的大小、默认值以及包装类 2.equals与==的区别 1).对于==,如果作用于基本数据类型...
    北玖i阅读 1,320评论 0 1
  • 1.面向对象的特征有哪些? 抽象:找出一些事物的相似和共性之处,然后将这些事物归为一类,这个类只考虑这些事物的相似...
    北玖i阅读 2,239评论 1 5
  • 在一个方法内部定义的变量都存储在栈中,当这个函数运行结束后,其对应的栈就会被回收,此时,在其方法体中定义的变量将不...
    Y了个J阅读 4,420评论 1 14
  • 目录:一、Java 基础二、容器三、多线程四、反射五、对象拷贝六、异常七、设计模式八、网络编程 欢迎评论留言,文章...
    mumuxi_阅读 777评论 0 13