设为首页收藏本站

职业吧

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 397|回复: 1

基础(21,30)

[复制链接]

15

主题

15

帖子

53

积分

网站编辑

Rank: 8Rank: 8

积分
53
发表于 2017-2-3 23:06:57 | 显示全部楼层 |阅读模式
21、描述一下JVM加载class文件的原理机制??
答:JVM中类的装载是由类加载器(ClassLoader)和它的子类来实现的,Java中的类加载器是一个重要的Java运行时系统组件,它负责在运行时查找和装入类文件中的类。?
由于Java的跨平台性,经过编译的Java源程序并不是一个可执行程序,而是一个或多个类文件。当Java程序需要使用某个类时,JVM会确保这个类已经被加载、连接(验证、准备和解析)和初始化。类的加载是指把类的.class文件中的数据读入到内存中,通常是创建一个字节数组读入.class文件,然后产生与所加载类对应的Class对象。加载完成后,Class对象还不完整,所以此时的类还不可用。当类被加载后就进入连接阶段,这一阶段包括验证、准备(为静态变量分配内存并设置默认的初始值)和解析(将符号引用替换为直接引用)三个步骤。最后JVM对类进行初始化,包括:1)如果类存在直接的父类并且这个类还没有被初始化,那么就先初始化父类;2)如果类中存在初始化语句,就依次执行这些初始化语句。?
类的加载是由类加载器完成的,类加载器包括:根加载器(BootStrap)、扩展加载器(Extension)、系统加载器(System)和用户自定义类加载器(java.lang.ClassLoader的子类)。从Java 2JDK 1.2)开始,类加载过程采取了父亲委托机制(PDM)。PDM更好的保证了Java平台的安全性,在该机制中,JVM自带的Bootstrap是根加载器,其他的加载器都有且仅有一个父类加载器。类的加载首先请求父类加载器加载,父类加载器无能为力时才由其子类加载器自行加载。JVM不会向Java程序提供对Bootstrap的引用。下面是关于几个类加载器的说明:
?Bootstrap:一般用本地代码实现,负责加载JVM基础核心类库(rt.jar);
?Extension:从java.ext.dirs系统属性所指定的目录中加载类库,它的父加载器是Bootstrap
?System:又叫应用类加载器,其父类是Extension。它是应用最广泛的类加载器。它从环境变量classpath或者系统属性java.class.path所指定的目录中记载类,是用户自定义加载器的默认父加载器。
22char 型变量中能不能存贮一个中文汉字,为什么??
答:char类型可以存储一个中文汉字,因为Java中使用的编码是Unicode(不选择任何特定的编码,直接使用字符在字符集中的编号,这是统一的唯一方法),一个char类型占2个字节(16比特),所以放一个中文是没问题的。
补充:使用Unicode意味着字符在JVM内部和外部有不同的表现形式,在JVM内部都是Unicode,当这个字符被从JVM内部转移到外部时(例如存入文件系统中),需要进行编码转换。所以Java中有字节流和字符流,以及在字符流和字节流之间进行转换的转换流,如InputStreamReaderOutputStreamReader,这两个类是字节流和字符流之间的适配器类,承担了编码转换的任务;对于C程序员来说,要完成这样的编码转换恐怕要依赖于union(联合体/共用体)共享内存的特征来实现了。
23、抽象类(abstract class)和接口(interface)有什么异同??
答:抽象类和接口都不能够实例化,但可以定义抽象类和接口类型的引用。一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现,否则该类仍然需要被声明为抽象类。接口比抽象类更加抽象,因为抽象类中可以定义构造器,可以有抽象方法和具体方法,而接口中不能定义构造器而且其中的方法全部都是抽象方法。抽象类中的成员可以是private、默认、protectedpublic的,而接口中的成员全都是public的。抽象类中可以定义成员变量,而接口中定义的成员变量实际上都是常量。有抽象方法的类必须被声明为抽象类,而抽象类未必要有抽象方法。
24、静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同??
答:Static Nested Class是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化,其语法看起来挺诡异的,
面试题 - 下面的代码哪些地方会产生编译错误?
class Outer {
    class Inner {}
    public static void foo() { new Inner(); }
    public void bar() { new Inner(); }
    public static void main(String[] args) {
        new Inner();
    }
}
注意:Java中非静态内部类对象的创建要依赖其外部类对象,上面的面试题中foomain方法都是静态方法,静态方法中没有this,也就是说没有所谓的外部类对象,因此无法创建内部类对象,如果要在静态方法中创建内部类对象,可以这样做:
    new Outer().new Inner();
25Java 中会存在内存泄漏吗,请简单描述。?
答:理论上Java因为有垃圾回收机制(GC)不会存在内存泄露问题(这也是Java被广泛使用于服务器端编程的一个重要原因);然而在实际开发中,可能会存在无用但可达的对象,这些对象不能被GC回收,因此也会导致内存泄露的发生。例如hibernateSession(一级缓存)中的对象属于持久态,垃圾回收器是不会回收这些对象的,然而这些对象中可能存在无用的垃圾对象,如果不及时关闭(close)或清空(flush)一级缓存就可能导致内存泄露。下面例子中的代码也会导致内存泄露。
import java.util.Arrays;
import java.util.EmptyStackException;
public class MyStack<T> {
    private T[] elements;
    private int size = 0;
    private static final int INIT_CAPACITY = 16;
    public MyStack() {
        elements = (T[]) new Object[INIT_CAPACITY];
    }
    public void push(T elem) {
        ensureCapacity();
        elements[size++] = elem;
    }
    public T pop() {
        if(size == 0)
            throw new EmptyStackException();
        return elements[--size];
    }
    private void ensureCapacity() {
        if(elements.length == size) {
            elements = Arrays.copyOf(elements, 2 * size + 1);
        }
    }
}
上面的代码实现了一个栈(先进后出(FILO))结构,乍看之下似乎没有什么明显的问题,它甚至可以通过你编写的各种单元测试。然而其中的pop方法却存在内存泄露的问题,当我们用pop方法弹出栈中的对象时,该对象不会被当作垃圾回收,即使使用栈的程序不再引用这些对象,因为栈内部维护着对这些对象的过期引用(obsolete reference)。在支持垃圾回收的语言中,内存泄露是很隐蔽的,这种内存泄露其实就是无意识的对象保持。如果一个对象引用被无意识的保留起来了,那么垃圾回收器不会处理这个对象,也不会处理该对象引用的其他对象,即使这样的对象只有少数几个,也可能会导致很多的对象被排除在垃圾回收之外,从而对性能造成重大影响,极端情况下会引发Disk Paging(物理内存与硬盘的虚拟内存交换数据),甚至造成OutOfMemoryError
26、抽象的(abstract)方法是否可同时是静态的(static,是否可同时是本地方法(native),是否可同时被synchronized修饰??
答:都不能。抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。本地方法是由本地代码(如C代码)实现的方法,而抽象方法是没有实现的,也是矛盾的。synchronized和方法的实现细节有关,抽象方法不涉及实现细节,因此也是相互矛盾的。
27、阐述静态变量和实例变量的区别。?
答:静态变量是被static修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝;实例变量必须依存于某一实例,需要先创建对象然后通过对象才能访问到它。静态变量可以实现让多个对象共享内存。
补充:在Java开发中,上下文类和工具类中通常会有大量的静态成员。
28、是否可以从一个静态(static)方法内部发出对非静态(non-static)方法的调用??
答:不可以,静态方法只能访问静态成员,因为非静态方法的调用要先创建对象,在调用静态方法时可能对象并没有被初始化。
29、如何实现对象克隆??
答:有两种方式:?
??1). 实现Cloneable接口并重写Object类中的clone()方法;?
??2). 实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆,代码如下。
import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;
public class MyUtil {
    private MyUtil() {
        throw new AssertionError();
    }
    @SuppressWarnings("unchecked")
    public static <T extends Serializable> T clone(T obj) throws Exception {
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bout);
        oos.writeObject(obj);
        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bin);
        return (T) ois.readObject();
        // 说明:调用ByteArrayInputStreamByteArrayOutputStream对象的close方法没有任何意义
        // 这两个基于内存的流只要垃圾回收器清理对象就能够释放资源,这一点不同于对外部资源(如文件流)的释放
    }
}
基于序列化和反序列化实现的克隆不仅仅是深度克隆,更重要的是通过泛型限定,可以检查出要克隆的对象是否支持序列化,这项检查是编译器完成的,不是在运行时抛出异常,这种是方案明显优于使用Object类的clone方法克隆对象。让问题在编译的时候暴露出来总是好过把问题留到运行时。
30GC是什么?为什么要有GC?
答:GC是垃圾收集的意思,内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。Java程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:System.gc() Runtime.getRuntime().gc() ,但JVM可以屏蔽掉显示的垃圾回收调用。?
垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低优先级的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。在Java诞生初期,垃圾回收是Java最大的亮点之一,因为服务器端的编程需要有效的防止内存泄露问题,然而时过境迁,如今Java的垃圾回收机制已经成为被诟病的东西。移动智能终端用户通常觉得iOS的系统比Android系统有更好的用户体验,其中一个深层次的原因就在于Android系统中垃圾回收的不可预知性。
补充:垃圾回收机制有很多种,包括:分代复制垃圾回收、标记垃圾回收、增量垃圾回收等方式。标准的Java进程既有栈又有堆。栈保存了原始型局部变量,堆保存了要创建的对象。Java平台对堆内存回收和再利用的基本算法被称为标记和清除,但是Java对其进行了改进,采用“分代式垃圾收集”。这种方法会跟Java对象的生命周期将堆内存划分为不同的区域,在垃圾收集过程中,可能会将对象移动到不同区域:?
- 伊甸园(Eden):这是对象最初诞生的区域,并且对大多数对象来说,这里是它们唯一存在过的区域。?
- 幸存者乐园(Survivor):从伊甸园幸存下来的对象会被挪到这里。?
- 终身颐养园(Tenured):这是足够老的幸存对象的归宿。年轻代收集(Minor-GC)过程是不会触及这个地方的。当年轻代收集不能把对象放进终身颐养园时,就会触发一次完全收集(Major-GC),这里可能还会牵扯到压缩,以便为大对象腾出足够的空间。
与垃圾回收相关的JVM参数:
?-Xms / -Xmx — 堆的初始大小 / 堆的最大大小
?-Xmn — 堆中年轻代的大小
?-XX:-DisableExplicitGC — 让System.gc()不产生任何作用
?-XX:+PrintGCDetails — 打印GC的细节
?-XX:+PrintGCDateStamps — 打印GC操作的时间戳
?-XX:NewSize / XX:MaxNewSize — 设置新生代大小/新生代最大大小
?-XX:NewRatio — 可以设置老生代和新生代的比例
?-XXrintTenuringDistribution — 设置每次新生代GC后输出幸存者乐园中对象年龄的分布
?-XX:InitialTenuringThreshold / -XX:MaxTenuringThreshold:设置老年代阀值的初始值和最大值
?-XX:TargetSurvivorRatio:设置幸存区的目标使用率

回复

使用道具 举报

0

主题

1

帖子

9

积分

新手上路

Rank: 1

积分
9
发表于 2017-11-10 10:44:25 | 显示全部楼层
  嫁得好的面相

  1.鼻梁高耸:夫星好

  一般来说,女性能否嫁得如意郎君,其中最重要就是看看鼻子。我们知道在面相学来说,由于鼻是代表“夫星”,因此只要看鼻就能知夫。女性的鼻不需过大,最重要是“规规正正,无起节及歪斜”,达到这个基本的条件,就有机会觅得如意郎君。此外,鼻相还有一点要注意,就是两边鼻翼要匀称有肉,鼻梁要丰隆及高耸。如果鼻子高但削,鼻梁低而扁都不算合格。

  2.颧部适中:助夫事业

  还有就是,除了鼻子要生得好之外,还要与颧部和合术互相配合,才能相得益彰。女性以鼻为夫星,双颧就是旁边的拱卫,代表丈夫的支持力。不少成功男人背后不止要有个好太太,还需要一个在工作上能帮一把的贤内助,令事业更上一层楼,财富自然滚滚来,因此女性的颧部正是丈夫会否有得力助手的指标。女性理想的颧部不宜过高,和合术

  亦不宜太大,最好大小适中,鼻和颧合比例,并非一味多肉就是福相。相反,如果颧骨太高鼻子又大,该女性极有可能事业心太重,好胜逞强,虽然能力出众,但太好算命

  胜反而容易与丈夫起争执,到非嫁给好丈夫并能白首偕老之相了。

  3.下巴够圆:嫁得贵人

  星座屋面相术学解说,下巴代表贵人,下巴生得浑圆的女和合术

  性除可旺夫之外,夫君也是其贵人,两人相辅相成。另外,下巴在相学上也称为“地阁”,是代表下一代的部位。下巴浑圆有肉,代表有“后福”,即表示下一代十分和合术

  乖巧,能孝顺父母,还可以继承父亲的事业。

  4.额阔平满:夫家有护荫

  如果,女性生得鼻高颧好,说明很有机会嫁入豪门。其中丈夫是白手兴家,或是继承父荫的,其实可以在面相中看到。在女性面相之中,额代表丈夫有父母作靠山。女算命

  人额头生得平满宽阔,代表夫家有祖业留下来。而额好还代表与家中长辈缘分好,两代沟通没问题,绝少会发生婆媳纠纷,而影响大家感情。 推荐阅读:嫁得好的女人面相

  容易嫁得好的女人面相

  第一、鼻准浑圆、鼻梁不陷

  得老公疼、老公事业有成。鼻准要有肉,不能太大太小,更不能鼻头尖,而且鼻梁不可以陷下去,有这样的鼻子的女生可以吸引好的男人,自然可以嫁给好老公。

  第二、下巴宽厚:公婆疼、夫家有祖产

  下巴宽厚的女心情很好,很愉快,不但嫁的老公家中有祖产,而且公公婆婆也会很疼爱。

  第三、天仓开阔

  老公出身豪门、相处愉快。

  眉毛尾巴跟头发之间叫做天仓,天仓开阔的女人除了本和合术

  身容易得到祖先的荫泽,而且也可以嫁个好老公。

  第四、耳珠垂

  老公白手起家、妯娌好相处。耳朵太小没有珠的人个性很急躁,因此跟妯娌相处时自然口舌是非会比较多,耳朵代表钱财,有珠的人通常父母亲一定会留财产,就算没有留,她的老公自己也会白手起家。

  第五、嘴巴菱角分明

  老公有大房子又体贴。嘴巴菱角嘴,而且略略上扬,不讲话时像在微笑的女人很注重生活品质,因此在恋爱选择的过程中,选到的老公通常会让她生活品质不错,因此往往都会有蛮不错的房子。











算命|seo
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|职业助手吧    

GMT+8, 2018-2-20 05:58 , Processed in 0.091765 second(s), 27 queries , Gzip On.

Powered by zhiye8.net

© 2016-2017 zhiye8.net

快速回复 返回顶部 返回列表