面试经常问的Java基础

String 能被继承吗?为什么?

1、不可以,String类有final修饰符,而final修饰符类是不可以被继承的。

2、平时定义的String str = “a” 与 String str = new String(“a”)还是有差别的

①前者默认调用的是String.valueOf来返回String实例对象,至于调用哪个取决于赋值,

比如String num=1,调用的是 
publicstatic String valueOf(int i) { 
return Integer.toString(i); 
}

后者则是调用如下部分: 
public String(String original) { 
this.value = original.value; 
this.hash = original.hash; 

最后我们的变量都存储在一个char数组中 
private final char value[];

有abcd字符串,最终输出是dcba

StringBuffer str1 = new StringBuffer("abcdef");

System.out.print(str1.reverse() + "----");

String,StringBuffer,StringBuilder的区别

String字符串常量(final修饰,不可被继承),String是常量创建之后不能更改

StringBuffer字符串变量(线程安全),也是final修饰,不允许被继承,其中绝大多数方法进行了同步处理,包括常用的Append方法也做了同步处理(synchronized修饰)。其自jdk1.0起就已经出现。其toString方法会进行对象缓存,以减少元素复制开销。 
public synchronized String toString() { 
if (toStringCache == null) { 
toStringCache = Arrays.copyOfRange(value, 0, count); 

return new String(toStringCache, true); 
}

StringBuilder字符串变量(非线程安全)其自jdk1.5起开始出现。与StringBuffer一样都继承和实现了同样的接口和类,方法除了没使用synch修饰以外基本一致,不同之处在于最后toString的时候,会直接返回一个新对象。 
public String toString() { 
// Create a copy, don’t share the array 
return new String(value, 0, count); 
}

ArrayList和LinkedList有什么区别

ArrayList和LinkedList都实现了List接口,有以下的不同点: 
1、ArrayList是基于索引的数据接口,它的底层是数组。它可以以O(1)时间复杂度对元素进行随机访问。与此对应,LinkedList是以元素列表的形式存储它的数据,每一个元素都和它的前一个和后一个元素链接在一起,在这种情况下,查找某个元素的时间复杂度是O(n)。 
2、相对于ArrayList,LinkedList的插入,添加,删除操作速度更快,因为当元素被添加到集合任意位置的时候,不需要像数组那样重新计算大小或者是更新索引。 
3、LinkedList比ArrayList更占内存,因为LinkedList为每一个节点存储了两个引用,一个指向前一个元素,一个指向下一个元素。

讲讲类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字段,当 new 的时候,他们的执行顺序。

此题考察的是类加载器实例化时进行的操作步骤(加载–>连接->初始化)。 
父类静态代变量、 
父类静态代码块、 
子类静态变量、 
子类静态代码块、 
父类非静态变量(父类实例成员变量)、 
父类构造函数、 
子类非静态变量(子类实例成员变量)、 
子类构造函数。 

用过哪些 Map 类,都有什么区别,HashMap 是线程安全的吗,并发下使用的 Map 是什么,他们内部原理分别是什么,比如存储方式, hashcode,扩容,默认容量等。

hashMap是线程不安全的,HashMap是数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的,采用哈希表来存储的

参照该链接:https://zhuanlan.zhihu.com/p/21673805 
JAVA8 的 ConcurrentHashMap 为什么放弃了分段锁,有什么问题吗,如果你来设计,你如何设计。 
参照:https://yq.aliyun.com/articles/36781

有没有有顺序的 Map 实现类,如果有, 他们是怎么保证有序的。

TreeMap和LinkedHashMap是有序的(TreeMap默认升序,LinkedHashMap则记录了插入顺序)。 
参照:http://uule.iteye.com/blog/1522291

抽象类和接口的区别,类可以继承多个类么,接口可以继承多个接口么,类可以实现多个接口么?

1、抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。 
2、抽象类要被子类继承,接口要被类实现。 
3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现 
4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。 
5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。 
6、抽象方法只能申明,不能实现。abstract void abc();不能写成abstract voidabc(){}。 
7、抽象类里可以没有抽象方法 
8、如果一个类里有抽象方法,那么这个类只能是抽象类 
9、抽象方法要被实现,所以不能是静态的,也不能是私有的。 
10、接口可继承接口,并可多继承接口,但类只能单根继承。

写出三种单例模式实现。

https://my.oschina.net/dyyweb/blog/609021

1、 懒汉,线程不安全

 

public class Singleton {

    private static Singletoninstance;

    private Singleton (){}

 

    public static synchronizedSingleton getInstance() {

   if (instance == null) {

      instance = new Singleton();

   }

   return instance;

    }

}

2、 饿汉

 

public class Singleton { 

    private static Singletoninstance = new Singleton(); 

    private Singleton (){} 

    public static SingletongetInstance() { 

    return instance; 

    } 

}

 

平时用到哪些 Linux 命令。

Ls,find,tar,tail,cp,rm,vi,grep,ps,pkill等等 

 

用一行命令查看文件的最后五行。

Tail -n 5 filename

用一行命令输出正在运行的 java 进程。

ps -ef|grep Java

如果有人恶意创建非法连接,怎么解决。

可以使用filter过滤处理

什么是 restful,讲讲你理解的 restful。

REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。 

高并发下,如何做到安全的修改同一行数据。

使用悲观锁 悲观锁本质是当前只有一个线程执行操作,结束了唤醒其他线程进行处理。 
也可以缓存队列中锁定主键。

重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?

方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。重载对返回类型没有特殊的要求。

Java 中会存在内存泄漏吗,请简单描述。

答:理论上Java因为有垃圾回收机制(GC)不会存在内存泄露问题(这也是Java被广泛使用于服务器端编程的一个重要原因);然而在实际开发中,可能会存在无用但可达的对象,这些对象不能被GC回收也会发生内存泄露。一个例子就是Hibernate的Session(一级缓存)中的对象属于持久态,垃圾回收器是不会回收这些对象的,然而这些对象中可能存在无用的垃圾对象。下面的例子也展示了Java中发生内存泄露的情况:

packagecom.lovo; 

  //何问起 hovertree.com

importjava.util.Arrays; 

importjava.util.EmptyStackException; 

 

publicclass MyStack<T> { 

    private T[] elements; 

    private int size = 0; 

    private static final int INIT_CAPACITY =16; 

     

    public MyStack() { 

        elements = (T[]) newObject[INIT_CAPACITY]; 

    } 

    public void push(T elem) { 

        ensureCapacity(); 

        elements[size++] = elem; 

    } 

    public T pop() { 

        if(size == 0)  

            throw newEmptyStackException(); 

        return elements[--size]; 

    } 

    private void ensureCapacity() { 

        if(elements.length == size) { 

            elements = Arrays.copyOf(elements,2 * size + 1); 

        } 

    } 

}

 

JavaIO中转换流的作用

Reader和Writer最重要的子类是InputStreamReader和OutputStreamWriter类

InputStreamReader类包含了一个底层输入流,可以从中读取原始字节。它根据指定的编码方式,将这些字节转换为Unicode字符。

OutputStreamWriter从运行的程序中接收Unicode字符,然后使用指定的编码方式将这些字符转换为字节,再将这些字节写入底层输出流中。

转换流的特点:

1. 其是字符流和字节流之间的桥梁

2. 可对读取到的字节数据经过指定编码转换成字符

3. 可对读取到的字符数据经过指定编码转换成字节

XML有哪些解析技术

1.DOM生成和解析XML文档

为 XML 文档的已解析版本定义了一组接口。解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用 DOM

接口来操作这个树结构。优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;使用

场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。

2.SAX生成和解析XML文档
 

为解决DOM的问题,出现了SAX。SAX

,事件驱动。当解析器发现元素开始、元素结束、文本、文档的开始或结束等时,发送事件,程序员编写响应这些事件的代码,保存数据。优点:不用事先调入整个文档,占用资

源少;SAX解析器代码比DOM解析器代码小,适于Applet,下载。缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;无状态性;从事件中只能得到文本,但不知该文

本属于哪个元素;使用场合:Applet;只需XML文档的少量内容,很少回头访问;机器内存少;

 
3.DOM4J生成和解析XML文档

DOM4J 是一个非常非常优秀的Java XML

API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写

XML,特别值得一提的是连 Sun 的 JAXM 也在用 DOM4J。

 
4.JDOM生成和解析XML  

为减少DOM、SAX的编码量,出现了JDOM;优点:20-80原则,极大减少了代码量。使用场合:要实现的功能简单,如解析、创建等,但在底层,JDOM还是使用SAX(最常用)、DOM、

Xanan文档。

四种会话跟踪技术,哪个范围最大?

A、Application         B、Page           C、Session                D、Request

会话跟踪技术 是保存用户和服务器之间,以上abcd不是会话跟踪(cookie,url重写,session,隐藏域),是JSP的四种范围----

JSP的四种属性范围:

page,request,session,application

page否是代表与一个页面相关的对象和属性。一个页面由一个编译好的Java servlet 类(可以带有任何的include 指令,但是没有include 动作)表示。这既包括servlet 又包括被编译成servlet JSP 页面

 request是是代表与 Web 客户机发出的一个请求相关的对象和属性。一个请求可能跨越多个页面,涉及多个Web 组件(由于forward 指令和include 动作的关系)

 session是代表与用于某个 Web 客户机的一个用户体验相关的对象和属性。一个Web 会话可以也经常会跨越多个客户机请求

 application是是代表与整个 Web 应用程序相关的对象和属性。这实质上是跨越整个Web 应用程序,包括多个页面、请求和会话的一个全局作用域

一、四种属性范围

1.1、在JSP中提供了四种属性保存范围

page:在一个页面内保存属性。跳转之后无效
request
:在一次服务请求范围内。server跳转后依旧有效
session
-在一次会话范围内,不管何种跳转都能够使用,可是新开浏览器无法使用
application
:在整个server上保存,全部用户都能够使用

1.2、4种属性范围都支持的操作

public void setAttribute(String name,Object value)
public Object getAttribute(String name)
public Object removeAttribute(String name)

二、bean的作用域

Singleton:单例-整个容器只有一个对象实例默认是单例

Prototype:原型-每次获取bean都产生一个新的对象

Request:每次请求时创建一个新的对象

Session:在会话的范围内是一个对象

Global session:--只在portlet下有用,表示application

Application:在应用范围中是一个对象

在一个JSP中,表达式<%=2+3%>,输出几?

输出5

jsp有哪些内置对象和动作?他们的作用分别是什么?

request 用户端请求,此请求会包含来自GET/POST请求的参数

response 网页传回用户端的回应

pageContext 网页的属性是在这里管理

session 与请求有关的会话期

application servlet 正在执行的内容

out 用来传送回应的输出

config servlet的构架部件

page JSP网页本身

exception 针对错误网页,未捕捉的例外

常用的组件:request、response、out、session、application、exception

阐述Struts框架的优缺点,并列举Hibernate中常用的主键生成方式

TODO:Struts中action需要实现特定的接口,所有的action只有一个实例,被反复调用

Hibernate中常用的主键:

1.assigned:

主键由外部程序负责生成,无需Hibernate参与。----如果要由程序代码来指定主键,就采有这种.

2.increment:

对 long , short 或 int 的数据列生成自动增长主键。increment主键生成方式的特点是与底层数据库无关性,大部分数据库如 Mysql,MSSQL 和ORACLE等都支持increament生成方式。此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。increment方式的不足之处是当多个线程并发对数据库表进行写操作时,可能出现相同的主键值,发生主键重复的冲突,因此多线程并发操作时,不应该使用此方法。

3. native

由Hibernate根据不同的数据库方言,自行判断采用identity、hilo、sequence其中一种作为Hibernate主键生成方式,native的 优点是与底层性无关,便于不同数据库之间的移植,由Hibernate根据不同数据库选择主键的生成方式。在oracle中需要创建叫 Hibernate_sequence名字的sequence,如果设置了Hibernate.hbm2ddl.auto属性,不需要手动建立序列,前提是数据库帐号必须有Create Sequence这种高级权限。mysql等数据库则不用建立sequence。

对于精度要求高的数学计算应使用哪个类型?如何进行运算?如何保留一定位数的小数并四舍五入?

一般的float型和Double型数据只可以用来做科学计算或者是工程计算,由于在商业计算中,要求的数字精度比较高,所以要用到java.math.BigDecimal类,它支持任何精度的定点数,可以用它来精确计算货币值。

BigDecimal b2 = newBigDecimal(1.23456789);//会造成精度丢失

        BigDecimal b1= newBigDecimal("1.23456789");//不会造成精度丢失

        b1.setScale(3, BigDecimal.ROUND_HALF_EVEN);//设置精度,在保留小数位时,要设置舍入模式

        System.out.println(b1.doubleValue());

        System.out.println(b1.floatValue());

        System.out.println(b1.longValue());

        System.out.println(b1.intValue());

        System.out.println(b1.toString());

System.out.println("四舍五入取整:1.23456789="

                   + new BigDecimal("1.25456789").setScale(1,BigDecimal.ROUND_HALF_UP));

结果:

1.23456789

1.2345679

1

1

1.23456789

1.3

日期格式字符串和日期类型之间如何互换?如何得到指定格式的日期字符串

Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2018-06-09");

         Stringnow = new SimpleDateFormat("yyyy年MM月dd日").format(date);

         System.out.println(now);

若已有栈A、B、C、D,则不可能的输出序列为?答:第二个

Abcd         dcba                   badc                   cdba

Strtus2的工作流程

1、客户端浏览器发出HTTP请求.

2、根据web.xml配置,该请求被FilterDispatcher接收

3、根据struts.xml配置,找到需要调用的Action类和方法, 并通过IoC方式,将值注入给Aciton

4、Action调用业务逻辑组件处理业务逻辑,这一步包含表单验证。

5、Action执行完毕,根据struts.xml中的配置找到对应的返回结果result,并跳转到相应页面

6、返回HTTP响应到客户端浏览器

SpringMVC的工作流程

1、用户发送请求至前端控制器DispatcherServlet 
2
DispatcherServlet收到请求调用HandlerMapping处理器映射器。 
3、处理器映射器找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。 
4DispatcherServlet调用HandlerAdapter处理器适配器 
5HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。 
6Controller执行完成返回ModelAndView 
7
HandlerAdaptercontroller执行结果ModelAndView返回给DispatcherServlet 
8
DispatcherServletModelAndView传给ViewReslover视图解析器 
9ViewReslover解析后返回具体View 
10
DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。 
11DispatcherServlet响应用户

SpringMVC与Struts2的主要区别?

springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。

springmvc基于方法开发,传递参数是通过方法形参,可以设计为单例或多例(建议单例)struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。 
Struts采用值栈存储请求和响应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request对象内容进行解析成方法形参,将响应数据和页面封装成ModelAndView对象,最后又将模型数据通过request对象传输到页面。 Jsp视图解析器默认使用jstl

1、存在使i + 1 < i的数吗()

答案:存在

解析:如果i为int型,那么当i为int能表示的最大整数时,i+1就溢出变成负数了,此时不就<i了吗。

扩展:存在使i > j || i <= j不成立的数吗()

答案:存在

解析:比如Double.NaN或Float.NaN,感谢@BuilderQiu网友指出。

2、不通过构造函数也能创建对象吗()

A 是     B

答案:A

解析:Java创建对象的几种方式(重要):

(1) 用new语句创建对象,这是最常见的创建对象的方法。
(2) 运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。
(3) 调用对象的clone()方法。
(4) 运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。

(1)和(2)都会明确的显式的调用构造函数 ;(3)是在内存上对已有对象的影印,所以不会调用构造函数;(4)是从文件中还原类的对象,也不会调用构造函数。

 

3、下面程序的运行结果是什么()

class HelloA {

 

   public HelloA() {

       System.out.println("HelloA");

    }

   

    {System.out.println("I'm A class"); }

   

   static { System.out.println("static A"); }

 

}

 

public class HelloB extends HelloA {

   public HelloB() {

       System.out.println("HelloB");

    }

   

    {System.out.println("I'm B class"); }

   

   static { System.out.println("static B"); }

   

   public static void main(String[] args) {

     new HelloB();

   }

 

}

结果:
static A
static B
I'm A class
HelloA
I'm B class
HelloB

对象的初始化顺序:(1)类加载之后,按从上到下(从父类到子类)执行被static修饰的语句;(2)当static语句执行完之后,再执行main方法;(3)如果有语句new了自身的对象,将从上到下执行构造代码块、构造器(两者可以说绑定在一起)

4、下面代码的运行结果为:()

import java.io.*;

import java.util.*;

 

public class foo{

 

   public static void main (String[] args){

 

       String s;

 

       System.out.println("s=" + s);

 

    }

 

}

代码得到编译,并输出“s=”

代码得到编译,并输出“s=null”

由于String s没有初始化,代码不能编译通过

代码得到编译,但捕获到 NullPointException异常

答案:C

解析:开始以为会输出null什么的,运行后才发现Java中所有定义的基本类型或对象都必须初始化才能输出值。


 

编程题:

输入三个整数x,y,z,把这三个数由小到大输出

有数字:2,5,7,9能组成多少个互不相同且无重复的数?

从键盘输入m和n,定义n是第一个数,之后的每个数都是前一个的平方根,共m个数,计算和

发布了5 篇原创文章 · 获赞 0 · 访问量 238

猜你喜欢

转载自blog.csdn.net/qq_31129841/article/details/79737191