牛客总结-JAVA篇(1)
1.线程安全的map在JDK 1.5及其更高版本环境 有哪几种方法可以实现?
Map map = new ConcurrentHashMap();
Map map = Collections.synchrolizedMap(new HashMap));
2. 1)调用super()必须写在子类构造方法的第一行,否则编译不通过。每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的
构造函数,那么在编译的时候就会报错。
2)super()和this()类似,区别是,super从子类中调用父类的构造方法,this()在同一类内调用其它方法。
3)super()和this()均需放在构造方法内第一行。
4)尽管可以用this调用一个构造器,但却不能调用两个。
5)this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个
构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。
6)this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。
7)从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。
3. 关键字super的作用是?
用来访问父类被隐藏的成员变量、用来调用父类中被重载的方法、用来调用父类的构造函数
4. 形式参数就是函数定义时设定的参数。例如函数头 int min(int x,int y,int z) 中 x,y,z 就是形参。实际参数是调用函数时所使用的实际的参数。真正被
传递的是实参。
形参可以是对象,是对象的时候传递引用。
对于形式参数只能用final修饰符,其它任何修饰符都会引起编译器错误 。但是用这个修饰符也有一定的限制,就是在方法中不能对参数做任何修改。 不过
一般情况下,一个方法的形参不用final修饰。只有在特殊情况下,那就是:方法内部类。
一个方法内的内部类如果使用了这个方法的参数或者局部变量的话,这个参数或局部变量应该是final。形式参数可被视为local variable。
5. A,我们写java程序的时候只是设定事物的隔离级别,而不是去实现它
B,Hibernate是一个java的数据持久化框架,方便数据库的访问
C,事物隔离级别由数据库系统实现,是数据库系统本身的一个功能
D,JDBC是java database connector,也就是java访问数据库的驱动
6. checked exception:指的是编译时异常,该类异常需要本函数必须处理的,用try和catch处理,或者用throws抛出异常,然后交给调用者去处理异常。
runtime exception:指的是运行时异常,该类异常不必须本函数必须处理,当然也可以处理。
Thread.sleep()抛出的InterruptException属于checked exception;IllegalArgumentException属于Runtime exception;
Thread.sleep() 和 Object.wait(),都可以抛出 InterruptedException。这个异常是不能忽略的,因为它是一个检查异常
7. 出于运行速率的考虑,java编译器会把经常经常访问的变量放到缓存(严格讲应该是工作内存)中,读取变量则从缓存中读。但是在多线程编程中,内存
中的值和缓存中的值可能会出现不一致。volatile用于限定变量只能从内存中读取,保证对所有线程而言,值都是一致的。但是volatile不能保证原子性,
也就不能保证线程安全。
volatile的两个特点:1.保证读取的可见性2.禁止指令重排
8. 类方法就是静态方法。其它的就是实例方法
实例方法可以对当前对象的实例变量进行操作,也可以对类变量进行操作,但类方法不能访问实例变量。实例方法必须由实例对象来调用,而类方法除了
可由实例对象调用外,还可以由类名直接调用。
另外,在类方法中不能使用 this 或 super。 关于类方法的使用,有如下一些限制:
1) 在类方法中不能引用对象变量。
2) 在类方法中不能使用super、this关键字。
3)类方法不能调用类中的对象方法。
与类方法相比,实例方法几乎没有什么限制:
1) 实例方法可以引用对象变量(这是显然的),也可以引用类变量。
2) 实例方法中可以使用super、this关键字。
3) 实例方法中可以调用类方法。
9. java中将ISO8859-1字符串转成GB2312编码,语句为 ?
注意这里”ISO8859-1″是一个普通字符串,不要被迷惑了
String.getBytes(“ISO8859-1″)表示获取这个字符串的byte数组,
然后new String(String.getBytes(“ISO8859-1″),GB2312)是上面的字符数组按照GB2312编码成新的字符串
10. java提供了一个系统级的线程,即垃圾回收器线程。用来对每一个分配出去的内存空间进行跟踪。当JVM空闲时,自动回收每块可能被回收的内存,
GC是完全自动的,不能被强制执行。程序员最多只能用System.gc()来建议执行垃圾回收器回收内存,但是具体的回收时间,是不可知的。
当对象的引用变量被赋值为null,可能被当成垃圾。
11. 反射最大程度破坏了面向对象的哪个特性?
mock对象:也称为伪对象,在测试中的利用mock对象来代替真实对象,方便测试的进行。
java的封装性:指的是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,通过该类提供的方法实现对内部信息的
操作访问。
反射机制:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性
12. 在类中不能constInt = constInt + 5; 方法中可以,类中不能进行运算,只能定义方法和变量
13. Java数据库连接库JDBC用到哪种设计模式?
桥接模式。JDBC提供两套接口,一个面向数据库厂商,一个面向JDBC使用者。
14. A: 垃圾回收线程在jvm中优先级相当相当低。
B:垃圾收集器(GC)程序开发者只能推荐JVM进行回收,但何时回收,回收哪些,程序员不能控制。
C:垃圾回收机制只是回收不再使用的JVM内存,如果程序有严重BUG,照样内存溢出。
D:进入DEAD的线程,它还可以恢复,GC不会回收
15. Java语言性特点:
Java致力于检查程序在编译和运行时的错误。
Java虚拟机实现了跨平台接口
类型检查帮助检查出许多开发早期出现的错误。
Java自己操纵内存减少了内存出错的可能性。
Java还实现了真数组,避免了覆盖数据的可能。
注意,是避免数据覆盖的可能,而不是数据覆盖类型
程序设计语言中,数组元素在内存中是一个接着一个线性存放的,通过第一个元素就能访问随后的元素,这样的数组称之为“真数组”。
实现了真数组为Java语言健壮性的特点之一。
16. 初始化过程:
1). 初始化父类中的静态成员变量和静态代码块 ;
2). 初始化子类中的静态成员变量和静态代码块 ;
3).初始化父类的普通成员变量和代码块,再执行父类的构造方法;
4).初始化子类的普通成员变量和代码块,再执行子类的构造方法;
17. instanceof运算符能够用来判断一个对象是否为:
一个类的实例、一个子类的实例、一个实现指定接口的类的实例(看实际类型)
18. MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、
界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC
被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。
MVC只是将分管不同功能的逻辑代码进行了隔离,增强了可维护和可扩展性,增强代码复用性,因此可以减少代码重复。但是不保证减少代码量,
多层次的调用模式还有可能增加代码量
19. 一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:
1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
2)禁止进行指令重排序。
volatile只提供了保证访问该变量时,每次都是从内存中读取最新值,并不会使用寄存器缓存该值——每次都会从内存中读取。
而对该变量的修改,volatile并不提供原子性的保证。
由于及时更新,很可能导致另一线程访问最新变量值,无法跳出循环的情况
多线程下计数器必须使用锁保护。
对volatile变量的操作不会造成阻塞。
(http://blog.csdn.net/zgmzyr/article/details/9150095)
20. 由所有HashMap类的“collection 视图方法”所返回的迭代器都是快速失败的:在迭代器创建之后,如果从结构上对映射进行修改,除非通过
迭代器本身的 remove 方法,其他任何时间任何方式的修改,迭代器都将抛出ConcurrentModificationException。Hashtable和HashMap
的区别主要是前者是同步的,后者是快速失败机制保证
21. exception是JSP九大内置对象之一,其实例代表其他页面的异常和错误。只有当页面是错误处理页面时,即isErroePage为 true时,该对象才
可以使用。errorPage的实质就是JSP的异常处理机制,发生异常时才会跳转到 errorPage指定的页面,没必要给errorPage再设置一个errorPage。
所以当errorPage属性存在时, isErrorPage属性值为false
22. sleep和wait的区别有:
1),这两个方法来自不同的类分别是Thread和Object
2),最主要是sleep方法没有释放锁,而wait方法释放了锁,使得敏感词线程可以使用同步控制块或者方法。
3),wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用
synchronized(x){
x.notify()
//䈖者wait()
}
4),sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
23. 普通的java对象是通过new关键字把对应类的字节码文件加载到内存,然后创建该对象的。
反射是通过一个名为Class的特殊类,用Class.forName(“className”);得到类的字节码对象,然后用newInstance()方法在虚拟机内部构造
这个对象(针对无参构造函数)。
也就是说反射机制让我们可以先拿到java类对应的字节码对象,然后动态的进行任何可能的操作,包括
1)在运行时判断任意一个对象所属的类
2)在运行时构造任意一个类的对象
3)在运行时判断任意一个类所具有的成员变量和方法
4)在运行时调用任意一个对象的方法
这些都是反射的功能。
使用反射的主要作用是方便程序的扩展。
24. String str = new String(“abc”),“abc”在内存中是怎么分配的?
什么是字符串常量池?
JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存被成为字符串常量池或者字符串字面量池
工作原理:
当代码中出现字面量形式创建字符串对象时,JVM首先会对这个字面量进行检查,如果字符串常量池中存在相同内容的字符串对象的引用,
则将这个引用返回,否则新的字符串对象被创建,然后将这个引用放入字符串常量池,并返回该引用。
实现前提:
字符串常量池实现的前提条件就是Java中String对象是不可变的,这样可以安全保证多个变量共享同一个对象。如果Java中的String对象
可变的话,一个引用操作改变了对象的值,那么其他的变量也会受到影响,显然这样是不合理的。
更详细的关于字符串常量池: http://droidyue.com/blog/2014/12/21/string-literal-pool-in-java/
关于堆和栈:
Java中所有由类实例化的对象和数组都存放在堆内存中,无论是成员变量,局部变量,还是类变量,它们指向的对象都存储在堆内存中。
而栈内存用来存储局部变量和方法调用。
更详细的关于堆和栈的区别: http://droidyue.com/blog/2014/12/07/differences-between-stack-and-heap-in-java/
关于寄存器:
Java中运行时数据区有一个程序寄存器(又称程序计数器),该寄存器为线程私有。Java中的程序计数器用来记录当前线程中正在执行的指令。
如果当前正在执行的方法是本地方法,那么此刻程序计数器的值为undefined
关于JVM运行时数据区的区别: http://droidyue.com/blog/2014/12/21/java-runtime-data-areas/
关于本题目中,”abc”为字面量对象,其存储在堆内存中。而字符串常量池则存储的是字符串对象的一个引用。
25. 含有abstract修饰符的class即为抽象类,abstract类不能创建的实例对象。含有abstract方法的类必须定义为abstract class,abstract class
类中的方法不必是抽象的。abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方法。
如果的子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。
接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的
成员变量类型默认为public static final。
下面比较一下两者的语法区别:
1).抽象类可以有构造方法,接口中不能有构造方法。
2).抽象类中可以有普通成员变量,接口中没有普通成员变量
3).抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
4). 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然
eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
5). 抽象类中可以包含静态方法,接口中不能包含静态方法
6). 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,
并且默认即为public static final类型。
7). 一个类可以实现多个接口,但只能继承一个抽象类。
8).
抽象类和接口都不能被实例化
9) 优先选用接口,尽量少用抽象类
下面接着再说说两者在应用上的区别:
接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约。而抽象类在代码实现方面发挥作用,可以实现代码的重用,
例如,模板方法设计模式是抽象类的一个典型应用,假设某个项目的所有Servlet类都要用相同的方式进行权限判断、记录访问日志和处理异常,
那么就可以定义一个抽象的基类,让所有的Servlet都继承这个抽象基类,在抽象基类的service方法中完成权限判断、记录访问日志和处理异常
的代码,在各个子类中只是完成各自的业务逻辑代码
备注:先从总体解释抽象类和接口的基本概念,然后再比较两者的语法细节,最后再说两者的应用区别。
比较两者语法细节区别的条理是:先从一个类中的构造方法、普通成员变量和方法(包括抽象方法),静态变量和方法,继承性等6个方面逐一
去比较回答,接着从第三者继承的角度的回答,特别是最后用了一个典型的例子来展现自己深厚的技术功底。
26. Java使用了中间缓存变量机制:
i=i++;等同于:
temp=i; (等号右边的i)
i=i+1; (等号右边的i)
i=temp; (等号左边的i)
而i=++i;则等同于:
i=i+1;
temp=i;
i=temp;
jvm里面有两个存储区,一个是暂存区(是一个堆栈,以下称为堆栈),另一个是变量区。jvm会这样运行这条语句, JVM把count
值(其值是0)拷贝到临时变量区。步骤2 count值加1,这时候count的值是1。步骤3 返回临时变量区的值,注意这个值是0,没
修改过。步骤4 返回值赋值给count,此时count值被重置成0。 c/c++中没有另外设置一个临时变量或是临时空间来保存i,所有操作
都是在一个内存空间中完成的。所以答案是1
27. Java语言中的异常处理包括声明异常、抛出异常、捕获异常和处理异常四个环节。
throw用于抛出异常。
throws关键字可以在方法上声明该方法要抛出的异常,然后在方法内部通过throw抛出异常对象。
try是用于检测被包住的语句块是否出现异常,如果有异常,则抛出异常,并执行catch语句。
cacth用于捕获从try中抛出的异常并作出处理。
finally语句块是不管有没有出现异常都要执行的内容。
28. 数据成员和函数成员默认是default访问权限,同一个包下的所有类都可以访问
29. 会话跟踪是一种灵活、轻便的机制,它使Web上的状态编程变为可能。
HTTP是一种无状态协议,每当用户发出请求时,服务器就会做出响应,客户端与服务器之间的联系是离散的、非连续的。当用户在同一网站
的多个页面之间转换时,根本无法确定是否是同一个客户,会话跟踪技术就可以解决这个问题。当一个客户在多个页面间切换时,服务器会
保存该用户的信息。
有四种方法可以实现会话跟踪技术:URL重写、隐藏表单域、Cookie、Session。
1).隐藏表单域:<input type=”hidden”>,非常适合步需要大量数据存储的会话应用。
2).URL 重写:URL 可以在后面附加参数,和服务器的请求一起发送,这些参数为名字/值对。
3).Cookie:一个 Cookie 是一个小的,已命名数据元素。服务器使用 SET-Cookie 头标将它作为 HTTP响应的一部分传送到客户端,客户端
被请求保存 Cookie 值,在对同一服务器的后续请求使用一个Cookie 头标将之返回到服务器。与其它技术比较,Cookie 的一个优点是在
浏览器会话结束后,甚至在客户端计算机重启后它仍可以保留其值
4).Session:使用
setAttribute(String str,Object obj)方法将对象捆绑到一个会话
30. JVM内存配置参数:
-Xmx10240m -Xms10240m -Xmn5120m
-XXSurvivorRatio=3
,其最小内存值和Survivor区总大小分别是:
-Xmx:最大堆大小
-Xms:初始堆大小
-Xmn : 年轻代大小
-XXSurvivorRatio:年轻代中Eden区与Survivor区的大小比值
年轻代5120m, Eden:Survivor=3,Survivor区大小=1024m(Survivor区有两个,即将年轻代分为5份,每个Survivor区占一份),
总大小为2048m。
-Xms初始堆大小即最小内存值为10240m
31. A、for循环的话,很灵活,但是代码不够简洁.
B、System.arraycopy()源码。可以看到是native方法:native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,
而是在用其他语言(如C和C++)实现的文件中。 可以将native方法比作Java程序同C程序的接口。
C、copyOf不是System的方法,而是Arrays的方法,下面是源码,可以看到本质上是调用的arraycopy方法。,那么其效率必然是比不上
arraycopy的
D、clone的话,返回的是Object【】,需要强制转换。 一般用clone效率是最差的,
http://xuyuanshuaaa.iteye.com/blog/1046621
32. Java中子类默认调用父类的无参构造函数,若父类已经定义了自己的构造函数,这时要显式的调用父类的构造函数或显式写出父类的无参构造
函数,否则会编译报错
33. 如何获取ServletContext设置的参数值?
ServletContext
context = this.getServletContext();
String catalogFileName =
context.getInitParameter(“catalogFileName”);
34.加载驱动程序的方法:
调用方法 Class.forName、通过添加系统的jdbc.drivers属性、通过registerDriver方法注册
DriverManager.getConnection方法返回一个Connection对象,这是加载驱动之后才能进行的,不是加载驱动的方法,是获取数据库连接的方法
35. (1):“在Java里面参数传递都是按值传递”这句话的意思是:按值传递是传递的值的拷贝,按引用传递其实传递的是引用的地址值,所以统称
按值传递。
(2):在Java里面只有基本类型和按照下面这种定义方式的String是按值传递,其它的都是按引用传递。就是直接使用双引号定义字符串方式:
String str = “Java私塾”;
http://blog.sina.cn/dpool/blog/s/blog_5e1e51bb0100frc6.html
36. 实现了GBK编码字节流到UTF-8编码字节流的转换:
dst=new String(src,”GBK”).getBytes(“UTF-8”)
操作步骤就是先解码再编码
用new String(src,”GBK”)解码得到字符串
用getBytes(“UTF-8”)得到UTF8编码字节数组
37. 公式-n=~n+1可推出~n=-n-1
38. super.getClass() 得到的依然是runtime当前类,若要得到真正的父类,需要用super.getClass().getSuperclass()虽然这里写的是super,
但其实用this也一样
39. 如何处理循环引用问题?
http://droidyue.com/blog/2015/06/05/how-garbage-collector-handles-circular-references/
40.局部变量存在于栈区,全局变量存在于堆区
41. 使用ObjectOutputStream和ObjectInputStream可以将对象进行传输.
声明为static和transient类型的成员数据不能被串行化。因为static代表类的状态, transient代表对象的临时数据(瞬时变量修饰符)。
42. 算法包括0个或多个输入,1个或多个输出,中间有穷个处理过程。存储结构不属于算法结构
43. ServletContext对象:servlet容器在启动时会加载web应用,并为每个web应用创建唯一的servlet context对象,可以把ServletContext
看成是一个Web应用的服务器端组件的共享内存,在ServletContext中可以存放共享数据。ServletContext对象是真正的一个全局对象,
凡是web容器中的Servlet都可以访问。
整个web应用只有唯一的一个ServletContext对象
servletConfig对象:用于封装servlet的配置信息。从一个servlet被实例化后,对任何客户端在任何时候访问有效,但仅对servlet自身有效,
一个servlet的ServletConfig对象不能被另一个servlet访问。
44. java虚拟机的功能
(1)通过 ClassLoader 寻找和装载 class 文件
(2)解释字节码成为指令并执行,提供 class 文件的运行环境
(3)进行运行期间垃圾回收
(4)提供与硬件交互的平台
45. 如果当前reqeust中的HttpSession 为null,当传入参数为true时,就创建一个新的Session,否则返回null
46.java中基本类型取值范围:
byte : 0
-2^7—-2^7-1
short : 0 -2^15—-2^15-1
int : 0 -2^31—-2^31-1
long : 0 -2^63—-2^63-1
float : 0.0f -2^31—-2^31-1
double : 0.0d -2^63—-2^63-1
char : ‘
\u0000′ 0—-2^16-1
boolean: false true\false
47. application对象是共享的,多个用户共享一个,以此实现数据共享和通信
48.java鲁棒性的特点:
java能检查程序在编译和运行时的错误、java自己操纵内存减少了内存出错的可能性、java还实现了真数组,避免了覆盖数据的可能
java能运行虚拟机实现跨平台不属于鲁棒性
49. java不允许单独的方法,过程或函数存在,需要隶属于某一类中,java语言中的方法属于对象的成员,而不是类的成员。不过,其中静态方法
属于类的成员
50.获取结果集的方法有:
1).Statement sta=con.createStatement();
ResultSet rst=sta.executeQuery(“select * from book”);
2).PreparedStatement pst=con.prepareStatement(“select * from book”);
ResultSet rst=pst.executeQuery();