当前位置 博文首页 > M_Jack的博客:java面试题集中了好几篇的搜索的

    M_Jack的博客:java面试题集中了好几篇的搜索的

    作者:[db:作者] 时间:2021-08-02 12:33

    1、servlet执行流程

    客户端发出http请求,web服务器将请求转发到servlet容器,servlet容器解析url并根据web.xml找到相对应的servlet,并将request、response对象传递给找到的servlet,servlet根据request就可以知道是谁发出的请求,请求信息及其他信息,当servlet处理完业务逻辑后会将信息放入到response并响应到客户端。

    2、springMVC的执行流程

    springMVC是由dispatchservlet为核心的分层控制框架。首先客户端发出一个请求web服务器解析请求url并去匹配dispatchservlet的映射url,如果匹配上就将这个请求放入到dispatchservlet,dispatchservlet根据mapping映射配置去寻找相对应的handel,然后把处理权交给找到的handel,handel封装了处理业务逻辑的代码,当handel处理完后会返回一个逻辑视图modelandview给dispatchservlet,此时的modelandview是一个逻辑视图不是一个正式视图,所以dispatchservlet会通过viewresource视图资源去解析modelandview,然后将解析后的参数放到view中返回到客户端并展现。

    3、给定一个txt文件,如何得到某字符串出现的次数

    ?

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    File file =?new?File("E://test.txt");

    InputStream is =?new?FileInputStream(file);

    byte?b[] =?new?byte[1024];

    int?a = is.read(b);

    String str[] =?new?String(b,0,a).split("");

    int?count =?0;

    for(int?i =?0;i<str.length;i++){

    if("a".equals(str[i]))count++;

    }

    System.out.println(count);

    4、Java设计模式思想(单列模式,工厂模式,策略模式,共23种设计模式)

    a) 单例模式:单例模式核心只需要new一个实例对象的模式,比如数据库连接,在线人数等,一些网站上看到的在线人数统计就是通过单例模式实现的,把一个计时器存放在数据库或者内存中,当有人登陆的时候取出来加一再放回去,有人退出登陆的时候取出来减一再放回去,但是当有两个人同时登陆的时候,会同时取出计数器,同时加一,同时放回去,这样的话数据就会错误,所以需要一个全局变量的对象给全部人使用,只需要new出一个实例对象,这就是单例模式的应用,并且单例模式节省资源,因为它控制了实例对象的个数,并有利于gc回收。

    b) 策略模式:就是将几个类中公共的方法提取到一个新的类中,从而使扩展更容易,保证代码的可移植性,可维护性强。比如有个需求是写鸭子对象,鸭子有叫,飞,外形这三种方法,如果每个鸭子类都写这三个方法会出现代码的冗余,这时候我们可以把鸭子中的叫,飞,外形这三个方法提取出来,放到鸭父类中,让每个鸭子都继承这个鸭父类,重写这三个方法,这样封装的代码可移植性强,当用户提出新的需求比如鸭子会游泳,那么对于我们oo程序员来讲就非常简单了我们只需要在鸭父类中加一个游泳的方法,让会游泳的鸭子重写游泳方法就可以了。

    c) 工厂模式:简单的工厂模式主要是统一提供实例对象的引用,通过工厂模式接口获取实例对象的引用。比如一个登陆功能,后端有三个类,controller类,interface类,实现接口的实现类。当客户端发出一个请求,当请求传到controller类中时,controller获取接口的引用对象,而实现接口的实现类中封装好了登陆的业务逻辑代码。当你需要加一个注册需求的时候只需要在接口类中加一个注册方法,实现类中实现方法,controller获取接口的引用对象即可,不需要改动原来的代码,这种做法是的可拓展性强。

    5、冒泡排序、二分查找

    a) 冒泡

    ?

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    public?static?void?mp(int?a[]) {

    int?swap =?0;

    for?(int?i =?0; i < a.length; i++) {

    for?(int?j = i; j < a.length; j++) {

    if?(a[j] > a[i]) {

    swap = a[i];

    a[i] = a[j];

    a[j] = swap;

    }

    }

    }

    System.out.println(Arrays.toString(a));

    }

    b)二分查找

    ?

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    public?static?int?ef(int?a[],?int?tag) {

    int?first =?0;

    int?end = a.length;

    for?(int?i =?0; i < a.length; i++) {

    int?middle = (first + end) /?2;

    if?(tag == a[middle]) {

    return?middle;

    }

    if?(tag > a[middle]) {

    first = middle +?1;

    }

    if?(tag < a[middle]) {

    end = middle -?1;

    }

    }

    return?0;

    }

    6-8、对ajax的理解

    a) Ajax为异步请求,即局部刷新技术,在传统的页面中,用户需要点击按钮或者事件触发请求,到刷新页面,而异步技术为不需要点击即可触发事件,这样使得用户体验感增强,比如商城购物车的异步加载,当你点击商品时无需请求后台而直接动态修改参数。

    9、父类与子类之间的调用顺序(打印结果)

    a) 父类静态代码块

    b) 子类静态代码块

    c) 父类构造方法

    d) 子类构造方法

    e) 子类普通方法

    f) 重写父类的方法,则打印重写后的方法

    10、内部类与外部类的调用

    a) 内部类可以直接调用外部类包括private的成员变量,使用外部类引用的this.关键字调用即可

    b) 而外部类调用内部类需要建立内部类对象

    11、多线程

    a)一个进程是一个独立的运行环境,可以看做是一个程序,而线程可以看做是进程的一个任务,比如QQ是一个进程,而一个QQ窗口是一个线程。

    b)在多线程程序中,多线程并发可以提高程序的效率,cpu不会因为某个线程等待资源而进入空闲状态,它会把资源让给其他的线程。

    c)用户线程就是我们开发程序是创建的线程,而守护线程为系统线程,如JVM虚拟中的GC

    d)线程的优先级别:每一个线程都有优先级别,有限级别高的可以先获取CPU资源使该线程从就绪状态转为运行状态。也可以自定义线程的有限级别

    e)死锁:至少两个以上线程争取两个以上cpu资源,避免死锁就避免使用嵌套锁,只需要在他们需要同步的地方加锁和避免无限等待

    12、AOP与IOC的概念(即spring的核心)

    a) IOC:Spring是开源框架,使用框架可以使我们减少工作量,提高工作效率并且它是分层结构,即相对应的层处理对应的业务逻辑,减少代码的耦合度。而spring的核心是IOC控制反转和AOP面向切面编程。IOC控制反转主要强调的是程序之间的关系是由容器控制的,容器控制对象,控制了对外部资源的获取。而反转即为,在传统的编程中都是由我们创建对象获取依赖对象,而在IOC中是容器帮我们创建对象并注入依赖对象,正是容器帮我们查找和注入对象,对象是被获取,所以叫反转。

    b) AOP:面向切面编程,主要是管理系统层的业务,比如日志,权限,事物等。AOP是将封装好的对象剖开,找出其中对多个对象产生影响的公共行为,并将其封装为一个可重用的模块,这个模块被命名为切面(aspect),切面将那些与业务逻辑无关,却被业务模块共同调用的逻辑提取并封装起来,减少了系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。

    13、hibernate的核心思想

    a) Hibernate的核心思想是ROM对象关系映射机制。它是将表与表之间的操作映射成对象与对象之间的操作。也就是从数据库中提取的信息会自动按照你设置的映射要求封装成特定的对象。所以hibernate就是通过将数据表实体类的映射,使得对对象的修改对应数据行的修改。

    14、Struts1与Struts2的区别

    15、最优删除谋字符串的某个字符

    16-17、Arraylist与linkedlist的区别

    a) 都是实现list接口的列表,arraylist是基于数组的数据结构,linkedlist是基于链表的数据结构,当获取特定元素时,ArrayList效率比较快,它通过数组下标即可获取,而linkedlist则需要移动指针。当存储元素与删除元素时linkedlist效率较快,只需要将指针移动指定位置增加或者删除即可,而arraylist需要移动数据。

    18、数据库优化

    a) 选择合适的字段,比如邮箱字段可以设为char(6),尽量把字段设置为notnull,这样查询的时候数据库就不需要比较null值

    b) 使用关联查询( left join on)查询代替子查询

    c) 使用union联合查询手动创建临时表

    d) 开启事物,当数据库执行多条语句出现错误时,事物会回滚,可以维护数据库的完整性

    e) 使用外键,事物可以维护数据的完整性但是它却不能保证数据的关联性,使用外键可以保证数据的关联性

    f) 使用索引,索引是提高数据库性能的常用方法,它可以令数据库服务器以比没有索引快的多的速度检索特定的行,特别是对于max,min,order by查询时,效果更明显

    g) 优化的查询语句,绝大多数情况下,使用索引可以提高查询的速度,但如果sql语句使用不恰当的话,索引无法发挥它的特性。

    19、Tomcat服务器优化(内存,并发连接数,缓存)

    a) 内存优化:主要是对Tomcat启动参数进行优化,我们可以在Tomcat启动脚本中修改它的最大内存数等等。

    b) 线程数优化:Tomcat的并发连接参数,主要在Tomcat配置文件中server.xml中配置,比如修改最小空闲连接线程数,用于提高系统处理性能等等。

    c) 优化缓存:打开压缩功能,修改参数,比如压缩的输出内容大小默认为2KB,可以适当的修改。

    20、HTTP协议

    a) 常用的请求方法有get、post

    b) Get与post的区别:传送数据,get携带参数与访问地址传送,用户可以看见,这的话信息会不安全,导致信息泄露。而post则将字段与对应值封装在实体中传送,这个过程用户是不可见的。Get传递参数有限制,而post无限制。

    21、TCP/UDP协议

    22、Java集合类框架的基本接口有哪些

    a) Collection集合接口,List、set实现Collection接口,arraylist、linkedlist,vector实现list接口,stack继承vector,Map接口,hashtable、hashmap实现map接口

    23、类加载的过程

    a) 遇到一个新的类时,首先会到方法区去找class文件,如果没有找到就会去硬盘中找class文件,找到后会返回,将class文件加载到方法区中,在类加载的时候,静态成员变量会被分配到方法区的静态区域,非静态成员变量分配到非静态区域,然后开始给静态成员变量初始化,赋默认值,赋完默认值后,会根据静态成员变量书写的位置赋显示值,然后执行静态代码。当所有的静态代码执行完,类加载才算完成。

    24、对象的创建

    a) 遇到一个新类时,会进行类的加载,定位到class文件

    b) 对所有静态成员变量初始化,静态代码块也会执行,而且只在类加载的时候执行一次

    c) New 对象时,jvm会在堆中分配一个足够大的存储空间

    d) 存储空间清空,为所有的变量赋默认值,所有的对象引用赋值为null

    e) 根据书写的位置给字段一些初始化操作

    f) 调用构造器方法(没有继承)

    25、jvm的优化

    a) 设置参数,设置jvm的最大内存数

    b) 垃圾回收器的选择

    26、高并发处理

    a) 了解一点高并发性问题,比如一W人抢一张票时,如何保证票在没买走的情况下所有人都能看见这张票,显然是不能用同步机制,因为synchronize是锁同步一次只能一个人进行。这时候可以用到锁机制,采用乐观锁可以解决这个问题。乐观锁的简单意思是在不锁定表的情况下,利用业务的控制来解决并发问题,这样即保证数据的可读性,又保证保存数据的排他性,保证性能的同时解决了并发带来的脏读数据问题。

    27、事物的理解

    a) 事物具有原子性,一致性,持久性,隔离性

    b) 原子性:是指在一个事物中,要么全部执行成功,要么全部失败回滚。

    c) 一致性:事物执行之前和执行之后都处于一致性状态

    d) 持久性:事物多数据的操作是永久性

    e) 隔离性:当一个事物正在对数据进行操作时,另一个事物不可以对数据进行操作,也就是多个并发事物之间相互隔离。

    28、Struts工作流程

    a) 客户端发出一个请求到servlet容器

    b) 请求经过一些列过滤被filterdispatcher调用,filterdispatch通过actionMapper去找相对应的action。

    c) Actionmapper找到对应的action返回给filterdispatch,dispatch把处理权交给actionproxy

    d) Actionproxy通过配置文件找到对应的action类

    e) Actionproxy创建一个actionIinvocation的实例处理业务逻辑

    f) 一旦action处理完毕,actioninvocation负责根据stuts.xml的配置找到对应的返回结果。返回结果通常是jsp页面。

    ?

    ?

    相关概念

    面向对象的三个特征

    封装,继承,多态,这个应该是人人皆知,有时候也会加上抽象。

    多态的好处

    允许不同类对象对同一消息做出响应,即同一消息可以根据发送对象的不同而采用多种不同的行为方式(发送消息就是函数调用)。主要有以下优点:

    1. 可替换性:多态对已存在代码具有可替换性

    2. 可扩充性:增加新的子类不影响已经存在的类结构

    3. 接口性:多态是超类通过方法签名,向子类提供一个公共接口,由子类来完善或者重写它来实现的。

    4. 灵活性

    5. 简化性

    代码中如何实现多态

    实现多态主要有以下三种方式:
    1. 接口实现?
    2. 继承父类重写方法?
    3. 同一类中进行方法重载

    虚拟机是如何实现多态的

    动态绑定技术(dynamic binding),执行期间判断所引用对象的实际类型,根据实际类型调用对应的方法。

    接口的意义

    接口的意义用三个词就可以概括:规范,扩展,回调。

    抽象类的意义

    抽象类的意义可以用三句话来概括:

    1. 为其他子类提供一个公共的类型

    2. 封装子类中重复定义的内容

    3. 定义抽象方法,子类虽然有不同的实现,但是定义时一致的

    接口和抽象类的区别

    比较抽象类接口
    默认方法抽象类可以有默认的方法实现java 8之前,接口中不存在方法的实现.
    实现方式子类使用extends关键字来继承抽象类.如果子类不是抽象类,子类需要提供抽象类中所声明方法的实现.子类使用implements来实现接口,需要提供接口中所有声明的实现.
    构造器抽象类中可以有构造器,接口中不能
    和正常类区别抽象类不能被实例化接口则是完全不同的类型
    访问修饰符抽象方法可以有public,protected和default等修饰接口默认是public,不能使用其他修饰符
    多继承一个子类只能存在一个父类一个子类可以存在多个接口
    添加新方法想抽象类中添加新方法,可以提供默认的实现,因此可以不修改子类现有的代码如果往接口中添加新方法,则子类中需要实现该方法.

    ?

    父类的静态方法能否被子类重写

    不能。重写只适用于实例方法,不能用于静态方法,而子类当中含有和父类相同签名的静态方法,我们一般称之为隐藏。

    什么是不可变对象

    不可变对象指对象一旦被创建,状态就不能再改变。任何修改都会创建一个新的对象,如 String、Integer及其它包装类。

    静态变量和实例变量的区别?

    静态变量存储在方法区,属于类所有。实例变量存储在堆当中,其引用存在当前线程栈。

    能否创建一个包含可变对象的不可变对象?

    当然可以创建一个包含可变对象的不可变对象的,你只需要谨慎一点,不要共享可变对象的引用就可以了,如果需要变化时,就返回原对象的一个拷贝。最常见的例子就是对象中包含一个日期对象的引用。

    java 创建对象的几种方式

    1. 采用new

    2. 通过反射

    3. 采用clone

    4. 通过序列化机制

    前2者都需要显式地调用构造方法。造成耦合性最高的恰好是第一种,因此你发现无论什么框架,只要涉及到解耦必先减少new的使用。

    switch中能否使用string做参数

    在idk 1.7之前,switch只能支持byte, short, char, int或者其对应的封装类以及Enum类型。从idk 1.7之后switch开始支持String。

    switch能否作用在byte, long上?

    可以用在byte上,但是不能用在long上。

    String s1=”ab”, String s2=”a”+”b”, String s3=”a”, String s4=”b”, s5=s3+s4请问s5==s2返回什么?

    返回false。在编译过程中,编译器会将s2直接优化为”ab”,会将其放置在常量池当中,s5则是被创建在堆区,相当于s5=new String(“ab”);

    你对String对象的intern()熟悉么?

    intern()方法会首先从常量池中查找是否存在该常量值,如果常量池中不存在则现在常量池中创建,如果已经存在则直接返回。
    比如?
    String s1=”aa”;?
    String s2=s1.intern();?
    System.out.print(s1==s2);//返回true

    Object中有哪些公共方法?

    1. equals()

    2. clone()

    3. getClass()

    4. notify(),notifyAll(),wait()

    5. toString

      ?

    java当中的四种引用

    强引用,软引用,弱引用,虚引用。不同的引用类型主要体现在GC上:

    1. 强引用:如果一个对象具有强引用,它就不会被垃圾回收器回收。即使当前内存空间不足,JVM也不会回收它,而是抛出 OutOfMemoryError 错误,使程序异常终止。如果想中断强引用和某个对象之间的关联,可以显式地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象。

    2. 软引用:在使用软引用时,如果内存的空间足够,软引用就能继续被使用,而不会被垃圾回收器回收,只有在内存不足时,软引用才会被垃圾回收器回收。

    3. 弱引用:具有弱引用的对象拥有的生命周期更短暂。因为当 JVM 进行垃圾回收,一旦发现弱引用对象,无论当前内存空间是否充足,都会将弱引用回收。不过由于垃圾回收器是一个优先级较低的线程,所以并不一定能迅速发现弱引用对象。

    4. 虚引用:顾名思义,就是形同虚设,如果一个对象仅持有虚引用,那么它相当于没有引用,在任何时候都可能被垃圾回收器回收。

    ?

    更多了解参见深入对象引用:

    http://blog.csdn.net/dd864140130/article/details/49885811

    WeakReference与SoftReference的区别?

    这点在四种引用类型中已经做了解释,这里简单说明一下即可:?
    虽然 WeakReference 与 SoftReference 都有利于提高 GC 和 内存的效率,但是 WeakReference ,一旦失去最后一个强引用,就会被 GC 回收,而软引用虽然不能阻止被回收,但是可以延迟到 JVM 内存不足的时候。

    为什么要有不同的引用类型

    不像C语言,我们可以控制内存的申请和释放,在Java中有时候我们需要适当的控制对象被回收的时机,因此就诞生了不同的引用类型,可以说不同的引用类型实则是对GC回收时机不可控的妥协。有以下几个使用场景可以充分的说明:

    1. 利用软引用和弱引用解决OOM问题:用一个HashMap来保存图片的路径和相应图片对象关联的软引用之间的映射关系,在内存不足时,JVM会自动回收这些缓存图片对象所占用的空间,从而有效地避免了OOM的问题.

    2. 通过软引用实现Java对象的高速缓存:比如我们创建了一Person的类,如果每次需要查询一个人的信息,哪怕是几秒中之前刚刚查询过的,都要重新构建一个实例,这将引起大量Person对象的消耗,并且由于这些对象的生命周期相对较短,会引起多次GC影响性能。此时,通过软引用和 HashMap 的结合可以构建高速缓存,提供性能。

    java中==和eqauls()的区别,equals()和`hashcode的区别

    ==是运算符,用于比较两个变量是否相等,而equals是Object类的方法,用于比较两个对象是否相等。默认Object类的equals方法是比较两个对象的地址,此时和==的结果一样。换句话说:基本类型比较用==,比较的是他们的值。默认下,对象用==比较时,比较的是内存地址,如果需要比较对象内容,需要重写equal方法。

    equals()hashcode()的联系

    hashCode()是Object类的一个方法,返回一个哈希值。如果两个对象根据equal()方法比较相等,那么调用这两个对象中任意一个对象的hashCode()方法必须产生相同的哈希值。
    如果两个对象根据eqaul()方法比较不相等,那么产生的哈希值不一定相等(碰撞的情况下还是会相等的。)

    a.hashCode()有什么用?与a.equals(b)有什么关系

    hashCode() 方法是相应对象整型的 hash 值。它常用于基于 hash 的集合类,如 Hashtable、HashMap、LinkedHashMap等等。它与 equals() 方法关系特别紧密。根据 Java 规范,使用 equal() 方法来判断两个相等的对象,必须具有相同的 hashcode。

    将对象放入到集合中时,首先判断要放入对象的hashcode是否已经在集合中存在,不存在则直接放入集合。如果hashcode相等,然后通过equal()方法判断要放入对象与集合中的任意对象是否相等:如果equal()判断不相等,直接将该元素放入集合中,否则不放入。

    有没有可能两个不相等的对象有相同的hashcode

    有可能,两个不相等的对象可能会有相同的 hashcode 值,这就是为什么在 hashmap 中会有冲突。如果两个对象相等,必须有相同的hashcode 值,反之不成立。

    可以在hashcode中使用随机数字吗?

    不行,因为同一对象的 hashcode 值必须是相同的

    a==b与a.equals(b)有什么区别

    如果a 和b 都是对象,则 a==b 是比较两个对象的引用,只有当 a 和 b 指向的是堆中的同一个对象才会返回 true,而 a.equals(b) 是进行逻辑比较,所以通常需要重写该方法来提供逻辑一致性的比较。例如,String 类重写 equals() 方法,所以可以用于两个不同对象,但是包含的字母相同的比较。

    3*0.1==0.3返回值是什么

    false,因为有些浮点数不能完全精确的表示出来。

    a=a+b与a+=b有什么区别吗?

    +=操作符会进行隐式自动类型转换,此处a+=b隐式的将加操作的结果类型强制转换为持有结果的类型,而a=a+b则不会自动进行类型转换。如:
    byte a = 127;?
    byte b = 127;?
    b = a + b; // error : cannot convert from int to byte?
    b += a; // ok?
    (译者注:这个地方应该表述的有误,其实无论 a+b 的值为多少,编译器都会报错,因为 a+b 操作会将 a、b 提升为 int 类型,所以将 int 类型赋值给 byte 就会编译出错)

    short s1= 1; s1 = s1 + 1; 该段代码是否有错,有的话怎么改?

    有错误,short类型在进行运算时会自动提升为int类型,也就是说s1+1的运算结果是int类型。

    short s1= 1; s1 += 1; 该段代码是否有错,有的话怎么改?

    +=操作符会自动对右边的表达式结果强转匹配左边的数据类型,所以没错。

    & 和 &&的区别

    首先记住&是位操作,而&&是逻辑运算符。另外需要记住逻辑运算符具有短路特性,而&不具备短路特性。

    ?
    1. public?class?Test{

    2. ? ?static?String name;

    3. ?
    4. ? ?public?static?void?main(String[] args){

    5. ? ? ? ?if(name!=null&userName.equals("")){

    6. ? ? ? ? ? ?System.out.println("ok");

    7. ? ? ? ?}else{

    8. ? ? ? ? ? ?System.out.println("erro");

    9. ? ? ? ?}

    10. ? ?}

    11. }

    ?

    以上代码将会抛出空指针异常。

    一个java文件内部可以有类?(非内部类)

    只能有一个public公共类,但是可以有多个default修饰的类。

    如何正确的退出多层嵌套循环?

    1. 使用标号和break;

    2. 通过在外层循环中添加标识符

      ?

      ?

    内部类的作用

    内部类可以有多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立.在单个外围类当中,可以让多个内部类以不同的方式实现同一接口,或者继承同一个类.创建内部类对象的时刻不依赖于外部类对象的创建。内部类并没有令人疑惑的”is-a”管系,它就像是一个独立的实体。

    内部类提供了更好的封装,除了该外围类,其他类都不能访问。

    final, finalize和finally的不同之处

    final 是一个修饰符,可以修饰变量、方法和类。如果 final 修饰变量,意味着该变量的值在初始化后不能被改变。finalize 方法是在对象被回收之前调用的方法,给对象自己最后一个复活的机会,但是什么时候调用 finalize 没有保证。finally 是一个关键字,与 try 和 catch 一起用于异常的处理。finally 块一定会被执行,无论在 try 块中是否有发生异常。

    clone()是哪个类的方法?

    java.lang.Cloneable 是一个标示性接口,不包含任何方法,clone 方法在 object 类中定义。并且需要知道 clone() 方法是一个本地方法,这意味着它是由 c 或 c++ 或 其他本地语言实现的。

    深拷贝和浅拷贝的区别是什么?

    浅拷贝:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象。

    深拷贝:被复制对象的所有变量都含有与原来的对象相同的值,而那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深拷贝把要复制的对象所引用的对象都复制了一遍。

    static都有哪些用法?

    几乎所有的人都知道static关键字这两个基本的用法:静态变量和静态方法。也就是被static所修饰的变量/方法都属于类的静态资源,类实例所共享。

    除了静态变量和静态方法之外,static也用于静态块,多用于初始化操作:

    ?
    1. public?calss PreCache{

    2. ? ?static{

    3. ? ? ? ?//执行相关操作

    4. ? ?}

    5. }

    ?

    此外static也多用于修饰内部类,此时称之为静态内部类。

    最后一种用法就是静态导包,即import static.import static是在JDK 1.5之后引入的新特性,可以用来指定导入某个类中的静态资源,并且不需要使用类名。资源名,可以直接使用资源名,比如:

    ?
    1. import?static?java.lang.Math.*;

    2. ?
    3. public?class?Test{

    4. ?
    5. ? ?public?static?void?main(String[] args){

    6. ? ? ? ?//System.out.println(Math.sin(20));传统做法

    7. ? ? ? ?System.out.println(sin(20));

    8. ? ?}

    9. }

    ?

    final有哪些用法

    final也是很多面试喜欢问的地方,能回答下以下三点就不错了:
    1.被final修饰的类不可以被继承?
    2.被final修饰的方法不可以被重写?
    3.被final修饰的变量不可以被改变。如果修饰引用,那么表示引用不可变,引用指向的内容可变。
    4.被final修饰的方法,JVM会尝试将其内联,以提高运行效率?
    5.被final修饰的常量,在编译阶段会存入常量池中。

    回答出编译器对final域要遵守的两个重排序规则更好:
    1.在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序。
    2.初次读一个包含final域的对象的引用,与随后初次读这个final域,这两个操作之间不能重排序。

    数据类型相关

    java中int char,long各占多少字节?

    类型位数字节数
    short216
    int432
    long864
    float432
    double864
    char216


    64位的JVM当中,int的长度是多少?

    Java 中,int 类型变量的长度是一个固定值,与平台无关,都是 32 位。意思就是说,在 32 位 和 64 位 的Java 虚拟机中,int 类型的长度是相同的。

    int和Integer的区别

    Integer是int的包装类型,在拆箱和装箱中,二者自动转换。int是基本类型,直接存数值,而integer是对象,用一个引用指向这个对象。

    int 和Integer谁占用的内存更多?

    Integer 对象会占用更多的内存。Integer是一个对象,需要存储对象的元数据。但是 int 是一个原始类型的数据,所以占用的空间更少。

    String, StringBuffer和StringBuilder区别

    String是字符串常量,final修饰:StringBuffer字符串变量(线程安全);
    StringBuilder 字符串变量(线程不安全)。

    String和StringBuffer

    String和StringBuffer主要区别是性能:String是不可变对象,每次对String类型进行操作都等同于产生了一个新的String对象,然后指向新的String对象。所以尽量不在对String进行大量的拼接操作,否则会产生很多临时对象,导致GC开始工作,影响系统性能。

    StringBuffer是对对象本身操作,而不是产生新的对象,因此在有大量拼接的情况下,我们建议使用StringBuffer。

    上一篇:没有了
    下一篇:没有了