一星题
方法重载:方法名称相同,参数列表不同(可以是参数的类型、个数、顺序不同)
方法重载满足的条件:
- 同一个类中,方法名相同,参数列表不同的2个或多个方法构成方法的重载
- 参数列表不同指参数的类型,参数的个数,参数的顺序至少一项不同
- 方法的返回值类型,方法的修饰符可以不同。
注意 ,如果两个方法只有返回值类型不同, 这两个方法在编译器看来还是同一个方法。
java源文件的后缀名是
.java
。源文件通过jvm虚拟机编译后会生成二进制字节码文件,后缀是
.class
。javac.exe是编译功能javaCompiler
java.exe是执行class如果没有编译的话是不能执行的,同理,javac.exe编译完以后如果没有java.exe执行的话也是没有运行的。
- 一个jvm中默认的classloader有Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader,分别各司其职:
- Bootstrap ClassLoader:负责加载java基础类,主要是 %JRE_HOME/lib/ 目录下的rt.jar、resources.jar、charsets.jar和class等。
- Extension ClassLoader:负责加载java扩展类,主要是 %JRE_HOME/lib/ext 目录下的jar和class。
- App ClassLoader:负责加载当前java应用的classpath中的所有类。
classloader 加载类用的是全盘负责委托机制。所谓全盘负责,即是当一个classloader加载一个Class的时候,这个Class所依赖的和引用的所有 Class也由这个classloader负责载入,除非是显式的使用另外一个classloader载入。
所以,当我们自定义的classloader加载成功了 com.company.MyClass以后,MyClass里所有依赖的class都由这个classLoader来加载完成。比较两个类是否相等,只有这两个类是由同一个类加载器加载才有意义。否则,即使这两个类是来源于同一个Class文件,只要加载它们的类加载器不同,那么这两个类必定不相等。
我们应用程序都是由以上三种类加载器互相配合进行加载的,还可以加入自己定义的类加载器。称为类加载器的双亲委派模型,这里类加载器之间的父子关系一般不会以继承的关系来实现,而是都使用组合关系来复用父加载器的。
优先级:单目>运算>移位>比较>按位>逻辑>三目>赋值
简记:淡云一笔安洛三幅。
- 动态 INCLUDE 用 jsp:include 动作实现 <jsp:include page=”included.jsp” flush=”true” /> 它总是会检查所含文件中的变化 , 适合用于包含动态页面 , 并且可以带参数。各个文件分别先编译,然后组合成一个文件。
- 静态 INCLUDE 用 include 伪码实现 , 定不会检查所含文件的变化 , 适用于包含静态页面 <%@ include file=”included.htm” %> 。先将文件的代码被原封不动地加入到了主页面从而合成一个文件,然后再进行翻译,此时不允许有相同的变量。
- 以下是对 include 两种用法的区别 , 主要有两个方面的不同:
一、执行时间上 :
<%@ include file=”relativeURI”%> 是在翻译阶段执行<jsp:include page="relativeURI" flush="true" /> 在请求处理阶段执行。 二、引入内容的不同 : <%@ include file="relativeURI"%> 引入静态文本 (html,jsp), 在 JSP 页面被转化成 servlet 之前和它融和到一起。 <jsp:include page="relativeURI" flush="true" /> 引入执行页面或 servlet 所生成的应答文本。
方法的重写需要满足:三同一大一小(方法名、返回值类型、形参相同;访问权限>=重写前;抛出异常<=重写前)
优先级高的并不一定会马上执行。
sleep方法会阻塞一个线程并不会终止。
创建一个新的线程时也不会终止另一个线程。
当抛出一个异常后程序会结束,所以线程也会被终止。
java中将ISO8859-1字符串转成GB2312编码,语句为 ?
new String(“ISO8859-1”.getBytes(“ISO8859-1”),”GB2312”)
创建并启动线程的过程为:定义线程—》实例化线程—》启动线程。
一 、定义线程:1、扩展java.lang.Thread类。 2、实现java.lang.Runnable接口。
二、实例化线程:
1、如果是扩展java.lang.Thread类的线程,则直接new即可。
2、如果是实现了java.lang.Runnable接口的类,则用Thread的构造方法:
1
2
3
4
5>Thread(Runnable target)
>Thread(Runnable target, String name)
>Thread(ThreadGroup group, Runnable target)
>Thread(ThreadGroup group, Runnable target, String name)
>Thread(ThreadGroup group, Runnable target, String name, long stackSize)Exception(异常)
是程序本身可以处理的异常。主要包含RuntimeException等运行时异常和IOException,SQLException等非运行时异常。
运行时异常
包括:都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。
非运行时异常(编译异常)
包括:RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。io流方面的知识:要将文件中一个字符写入另一个文件,首先要读入(FileInputStream)到内存中去,然后再读出(FileOutputStream)。
结构型模式是描述如何将类对象结合在一起,形成一个更大的结构,结构模式描述两种不同的东西:类与类的实例。故可以分为类结构模式和对象结构模式。
在GoF设计模式中,结构型模式有:
1.适配器模式 Adapter
适配器模式是将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
两个成熟的类需要通信,但是接口不同,由于开闭原则,我们不能去修改这两个类的接口,所以就需要一个适配器来完成衔接过程。
2.桥接模式 Bridge
桥接模式将抽象部分与它的实现部分分离,是它们都可以独立地变化。它很好的支持了开闭原则和组合锯和复用原则。实现系统可能有多角度分类,每一种分类都有可能变化,那么就把这些多角度分离出来让他们独立变化,减少他们之间的耦合。
3.组合模式 Composite
组合模式将对象组合成树形结构以表示部分-整体的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。
4.装饰模式 Decorator
装饰模式动态地给一个对象添加一些额外的职责,就增加功能来说,它比生成子类更灵活。也可以这样说,装饰模式把复杂类中的核心职责和装饰功能区分开了,这样既简化了复杂类,有去除了相关类中重复的装饰逻辑。
装饰模式没有通过继承原有类来扩展功能,但却达到了一样的目的,而且比继承更加灵活,所以可以说装饰模式是继承关系的一种替代方案。
5.外观模式 Facade
外观模式为子系统中的一组接口提供了同意的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
外观模式中,客户对各个具体的子系统是不了解的,所以对这些子系统进行了封装,对外只提供了用户所明白的单一而简单的接口,用户直接使用这个接口就可以完成操作,而不用去理睬具体的过程,而且子系统的变化不会影响到用户,这样就做到了信息隐蔽。
6.享元模式 Flyweight
享元模式为运用共享技术有效的支持大量细粒度的对象。因为它可以通过共享大幅度地减少单个实例的数目,避免了大量非常相似类的开销。
享元模式是一个类别的多个对象共享这个类别的一个对象,而不是各自再实例化各自的对象。这样就达到了节省内存的目的。
7.代理模式 Proxy
为其他对象提供一种代理,并由代理对象控制对原对象的引用,以间接控制对原对象的访问。
CGI(Common Gateway Interface),通用网关接口
通用网关接口,简称CGI,是一种根据请求信息动态产生回应内容的技术。通过CGI,Web服务器可以将根据请求不同启动不同的外部程序,并将请求内容转发给该程序,在程序执行结束后,将执行结果作为回应返回给客户端。也就是说,对于每个请求,都要产生一个新的进程进行处理。因为每个进程都会占有很多服务器的资源和时间,这就导致服务器无法同时处理很多的并发请求。另外CGI程序都是与操作系统平台相关的,虽然在互联网爆发的初期,CGI为开发互联网应用做出了很大的贡献,但是随着技术的发展,开始逐渐衰落。
Servlet
Servlet最初是在1995年由James Gosling
提出的,因为使用该技术需要复杂的Web服务器支持,所以当时并没有得到重视,也就放弃了。后来随着Web应用复杂度的提升,并要求提供更高的并发处理能力,Servlet被重新捡起,并在Java平台上得到实现,现在提起Servlet,指的都是Java Servlet。Java
Servlet要求必须运行在Web服务器当中,与Web服务器之间属于分工和互补关系。确切的说,在实际运行的时候Java Servlet与Web服务器会融为一体,如同一个程序一样运行在同一个Java虚拟机(JVM)当中。与CGI不同的是,Servlet对每个请求都是单独启动一个线程,而不是进程。这种处理方式大幅度地降低了系统里的进程数量,提高了系统的并发处理能力。另外因为Java Servlet是运行在虚拟机之上的,也就解决了跨平台问题。如果没有Servlet的出现,也就没有互联网的今天。
在Servlet出现之后,随着使用范围的扩大,人们发现了它的一个很大的一个弊端。那就是为了能够输出HTML格式内容,需要编写大量重复代码,造成不必要的重复劳动。为了解决这个问题,基于Servlet技术产生了JavaServet Pages技术,也就是JSP。Servlet和JSP两者分工协作,Servlet侧重于解决运算和业务逻辑问题,JSP则侧重于解决展示问题。Servlet与JSP一起为Web应用开发带来了巨大的贡献,后来出现的众多Java Web应用开发框架都是基于这两种技术的,更确切的说,都是基于Servlet技术的。
——————–分割线————————-- Servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁。
- 而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于Servlet 。
- CGI不可移植,为某一特定平台编写的CGI应用只能运行于这一环境中。每一个CGI应用存在于一个由客户端请求激活的进程中,并且在请求被服务后被卸载。这种模式将引起很高的内存、CPU开销,而且在同一进程中不能服务多个客户。
顶层容器是指可以不能被其他容器包含 ,是容纳其他容器的容器组件,
顶层容器包含JApplet、JDialog、JFrame和JWindow及其子类.
JFrame中就可以放Jtree(树形组件)。Java继承中对构造函数是不继承的,只是显式或者隐式调用。
Java中有两种方式实现线程:
class A继承Thread,并重写run方法,new A().start(),就执行了线程
class A实现Runnable,实现run方法,new Thread(new A()).start()
2.class A实现Runnable,实现run方法,new Thread(new A()).start()
当然以上方式run方法都是无返回值的,如果需要返回值,需要Callable接口。
public static void main (String[] args) { String classFile = "com.jd.". replaceAll(".", "/") + "MyClass.class"; System.out.println(classFile); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
由于replaceAll方法的第一个参数是一个正则表达式,而"."在正则表达式中表示任何字符,所以会把前面字符串的所有字符都替换成"/"。如果想替换的只是".",那么久要写成"\\."。故结果为`///////MyClass.class`。
19. 通过JDBC访问数据库包含下面哪几步?
- 载入JDBC驱动程序
- 建立连接
- 执行查询或更新
- 关闭连接
20. 重载对返回值没有要求,可以相同,也可以不同;但是如果参数的个数、类型、次序都相同,方法名也相同,仅返回值不同,则无法构成重载。
21. HashSet内部使用Map保存数据,即将HashSet的数据作为Map的key值保存,这也是HashSet中元素不能重复的原因。而Map中保存key值前,会去判断当前Map中是否含有该key对象,内部是先通过key的hashCode,确定有相同的hashCode之后,再通过equals方法判断是否相同。
22. > Character 字符封装类
>
>String 常量池中字符串
>
>StringBuffer 存放字符数组
>
>Vector 数组
23. 二维数组声明:
```java
int [][] table = new int[2][2];
int [][] table1 = new int[2][];
int [] table2 [] = new int[2][2];
int [] table3 [] = new int[2][];
int table4 [][] = new int[2][2];
int table5 [][] = new int[2][];- 接口中声明的成员变量默认为static final成员(不管是基础数据类型还是引用类型),且必须初始化;
- 接口中声明的方法默认为public且不能有实现体,即{},方法体可有参数;
- 实现接口的类,必须实现接口中所有方法,且不能降低方法的运用域,即必须显示声明为public;
- 抽象类不需要实现接口的方法。抽象类也可以实现接口,但是可以实现部分或者一个都不实现;
- 在jdk8之后添加了默认方法,在返回值加上default关键字,然后还有方法体;该接口被扩展时,可以直接继承或重新声明。还添加了静态方法。
非构造方法必须要有返回类型,其实构造方法的返回类型是void,只不过不能写出来而已。
局部变量的作用范围仅仅在定义它的方法内,或者是在定义它的控制流块中。
实例方法可直接调用本类的类方法。
在Applet中,方法执行的顺序是
init(), start(), paint(),stop(),destroy()
。局部变量是定义在方法中的变量,必须要进行初始化,否则不能通过编译。
class X{ Y y=new Y(); public X(){ System.out.print("X"); } } class Y{ public Y(){ System.out.print("Y"); } } public class Z extends X{ Y y=new Y(); public Z(){ System.out.print("Z"); } public static void main(String[] args) { new Z(); } }
初始化过程:
- 初始化父类中的静态成员变量和静态代码块 ;
- 初始化子类中的静态成员变量和静态代码块 ;
- 初始化父类的普通成员变量和代码块,再执行父类的构造方法;
- 初始化子类的普通成员变量和代码块,再执行子类的构造方法;
(1)初始化父类的普通成员变量和代码块,执行 Y y=new Y(); 输出Y
(2)再执行父类的构造方法;输出X
(3)初始化子类的普通成员变量和代码块,执行 Y y=new Y(); 输出Y
(4)再执行子类的构造方法;输出Z
所以输出YXYZ。客户端要获取一个socket对象通过实例化,而服务器获得一个socket对象则通过什么方法的返回值?
答:getRemoteSocketAddress()。
public class Example{ String str=new String("good"); char[]ch={'a','b','c'}; public static void main(String args[]){ Example ex=new Example(); ex.change(ex.str,ex.ch); System.out.print(ex.str+" and "); System.out.print(ex.ch); } public void change(String str,char ch[]){ //引用类型变量,传递的是地址,属于引用传递。 str="test ok"; ch[0]='g'; } }
Java方法调用中,只存在值传递调用。 此处,实参str是引用变量,由于java方法调用是值传递,所以形参str得到的是实参str的一个拷贝。此时形参str和实参str均指向字符串"1234"。 然后,在changeStr方法中,形参str指向了一个新的字符串"welcom",而后方法结束,形参str被销毁。而实参str仍然指向字符串"1234"。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
641、java语言参数之间只有值传递,包括按值调用和按引用调用。 一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。
按值调用:包括八大基本数据类型都是按值调用。传值的时候,也就是说方法得到的是所有参数值的一个拷贝。
按引用调用:数组、对象。传值时候,传递的是引用地址的拷贝,但是都是指向同一个对象。
2、String是不可变类(final and Immutable),这里只是把副本的指向修改成指向“test ok”,原地址str的指向的值没有发生改变。
3、运行结果为:good and gbc。
33. > 运行时数据区包括:虚拟机栈区,堆区,方法区,本地方法栈,程序计数器
>
>**虚拟机栈区**:也就是我们常说的栈区,**线程私有**,存放基本类型,对象的引用和returnAddress,在编译期间完成分配。
>
>**堆区**,JAVA堆,也称GC堆,所有**线程共享**,存放对象的实例和数组,JAVA堆是垃圾收集器管理的主要区域。
>
>**方法区**:所有**线程共享**,存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。这个区域的内存回收目标主要是针对常量池的对象的回收和对类型的卸载。
>
>**程序计数器**:**线程私有**,每个线程都有自己独立的程序计数器,用来指示下一条指令的地址。
34. Panel 和 Applet 的默认布局管理器是FlowLayout。
35. > 关于synchronized和volatile的比较:
>
>- 关键字volatile是线程同步的轻量级实现,所以volatile性能肯定比synchronized要好,并且只能修改变量,而synchronized可以修饰方法,以及代码块。
>- 多线程访问volatile不会发生阻塞,而synchronized会出现阻塞。
>- volatile能保证数据的可见性,但不能保证原子性;而synchronized可以保证原子性,也可以间接保证可见性,因为它会将私有内存和公共内存中的数据做同步。
>- 关键字volatile解决的是变量在多线程之间的可见性;而synchronized解决的是多线程之间资源同步问题。
36. finally语句块
- 不管catch是否捕获异常,finally语句块都是要被执行的
- 在try语句块或catch语句块中执行到System.exit(0)直接退出程序
- finally块中的return语句会覆盖try块中的return返回
- finally块中的内容会先于try中的return语句执行,如果finall语句块中也有return语句的话,那么直接从finally中返回了,但是不建议在finally中return。
37. > 类的复用有两种方式:组成(has-a)和继承(is-a)
> 1)组成就是在新的类中直接创建旧类的对象,这里我们复用的只是代码的功能而不是它的形式。
> 2)继承是在原有的类的基础上建立一个新类,新类具有旧类的形式,但也加入了一些新的特性。
>
> 继承:指一个新的类继承原有类的基本特性,并增加了新的特性。(Java不允许多继承,而C++可以)
>
> 多态性: 指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。
> 1)多态存在的三个必要条件
> ①要有继承 ②要有重写 ③父类引用指向子类对象(向上转型)
> 2)实现多态性的三种形式
> ①方法的重载 ②通过继承机制而产生方法覆盖 ③通过接口实现方法覆盖
> 3)多态的分类
> 多态分为编译时多态和运行时多态。其中编译 时多态是静态的,主要是指方法的重载,它是根据参数列表的不同来区分不同的函数,通过编译之后会变成两个不同的函数,在运行时谈不上多态。而运行时多态是动态的,它是通过动态绑定来实现的,也就是我们平常所说的多态性。
38. - Java中,赋值是有返回值的 ,赋什么值,就返回什么值。比如这题,x=y,返回y的值,所以括号里的值是1。
- Java跟C的区别,C中赋值后会与0进行比较,如果大于0,就认为是true;而Java不会与0比较,而是直接把赋值后的结果放入括号。
39. ```java
public class Test
{
public static void changeStr(String str)
{
str = "welcome";
}
public static void main(String[] args)
{
String str = "1234";
changeStr(str);
System.out.println(str);
}
}jvm堆分为:新生代(一般是一个Eden区,两个Survivor区),老年代(old区)。
常量池属于 PermGen(方法区)- 所有类的实例和数组都是在堆上分配内存的
- 对象所占的堆内存是由自动内存管理系统回收
- 堆内存由存活和死亡的对象,空闲碎片区组成
- CopyOnWriteArrayList适用于写少读多的并发场景
- ReadWriteLock即为读写锁,他要求写与写之间互斥,读与写之间互斥,读与读之间可以并发执行。在读多写少的情况下可以提高效率
- ConcurrentHashMap是同步的HashMap,读写都加锁
- volatile只保证多线程操作的可见性,不保证原子性
- ConcurrentHashMap实际上时 HashTable的升级版,使用segment来分段和管理锁,并不是synchronized;
- HashMap实现的接口有:Serializable, Cloneable, Map<K,V> ,没有实现Collection;
- Arrays.asList()方法返回的列表是Arrays.ArrayList类型的,并不是java.util.ArrayList;
- SimpleDateFormat是线程不安全的
private修饰的东西,只是不能在别的类中访问,但是本类中还是可以的。同时利用反射也可以做到。
JUnit主要用来完成单元测试。
- Log4j支持按分钟为间隔生成新的日志文件
- Log4j是一个打印日志用的组件
- Log4j支持按年为间隔生成新的日志文件
- Log4j的日志打印级别不可以在运行时重新设置
日志的级别之间的大小关系:ALL< TRACE< DEBUG< INFO< WARN< ERROR< FATAL< OFF。
Log4j建议只使用四个级别,优先级从高到低分别是 ERROR > WARN > INFO > DEBUG。
在类方法中不能有this关键字,this指的是当前对象,类方法依附于类而不是对象,使用this会编译出错。
下面哪种情况会导致持久区jvm堆内存溢出?
答:使用CGLib技术直接操作字节码运行,生成大量的动态类
在Struts框架中如果要使用Validation作验证的话,需要使用以下哪个Form?
答:DynaValidatorActionForm 动态验证表单
- 内部类前面可以修饰public,protected和private
- 外部类只能用 public、abstract、final修饰
- 单例模式中,两个基本要点是
- 构造函数私有
- 唯一实例
- 常用的servlet包的名称:
- javax.servlet
- javax.servlet.http
- 数组:
- 数组是一个对象,不同类型的数组具有不同的类
- 数组是一个连续的存储结构
二星题
- java.io.Serializable接口是一个标志性接口,在接口内部没有定义任何属性与方法。只是用于标志此接口的实现类可以被序列化与反序列化。
- java.lang.Cloneable接口是一个标志性接口,在接口内部没有定义任何属性与方法。以指示Object.clone()方法可以合法地对该类实例进行按字段复制。
- java.lang.CharSequence接口对许多不同种类的char序列提供统一的只读访问接口。CharSequence是char值的一个可读序列。
- java.lang.Comparable接口,此接口强制对实现它的每个类的对象进行整体排序,此序列被称为该类的自然排序。
需要注意的是,super关键字只能指代直接父类,不能指代父类的父类。
基本数据类型都是以小写字母开头,引用数据类型则是以大写字母开头。
Java的Daemon线程,setDaemon( )设置必须要在start之前。
释放掉占据的内存空间是由gc完成,但是程序员无法明确强制其运行,该空间在不被引用的时候不一定会立即被释放,这取决于GC本身,无法由程序员通过代码控制。
静态内部类不可以直接访问外围类的非静态数据,而非静态内部类可以直接访问外围类的数据,包括私有数据。
spring
- spring是一个轻量级JAVA EE的框架集合
- spring是“依赖注入”模式的实现
- 使用spring可以实现声明事务
转发重定向,转发的时候pageContent内的属性值不能被传递。
- HashMap,TreeMap 未进行同步考虑,是线程不安全的。
- HashTable 和 ConcurrentHashMap 都是线程安全的。区别在于他们对加锁的范围不同,HashTable 对整张Hash表进行加锁,而ConcurrentHashMap将Hash表分为16桶(segment),每次只对需要的桶进行加锁。
- Collections 类提供了synchronizedXxx()方法,可以将指定的集合包装成线程同步的集合。比如,
List list = Collections.synchronizedList(new ArrayList());
Set set = Collections.synchronizedSet(new HashSet());
以下方法可以取到http请求中的cookie值:
- request.getHeader
- request.getCookies
同一个类的对象使用不同的内存段,但静态成员共享相同的内存空间。
- 使用super()或者this()方法是必须放在构造函数的第一行。
- 由于this函数指向的构造函数默认有super()方法,所以规定this()和super()不能同时出现在一个构造函数中。
- 因为staic方法或者语句块没有实例时可以使用,而此时不需要构造实例,所以不能用this()和super()。
普通的类方法是可以和类名同名的,和构造方法唯一的区分就是,构造方法没有返回值。
1、List接口和Set接口都继承自Collection接口,Collection接口继承Iterable接口(Iterable有一个Iterator方法),即可迭代的;Collection只能存储引用类型,并且是单个存储;
2、List接口存储元素特点:有序(存进去什么顺序取出来还什么顺序),可重复;Set接口存储元素特点:无序,不可重复
3、实现List接口主要的类包括ArrayList,LinkedList,Vector;实现Set的主要类包括:hashSet,另外还有一个TreeSet接口继承它(自动排序)
4、Map接口以键值对方式存储元素,键无序不可重复,Map和Collection没有任何关系一个完整的URL地址由协议,主机名,端口和文件四部分组成。
泛型只在编译的时候保证数据类型的正确性,和运行期间的性能无关。
- 用new创建的对象在堆区
- 函数中的临时变量在栈去
- java中的字符串在字符串常量区
- HashMap不能保证元素的顺序,HashMap能够将键设为null,也可以将值设为null
- Hashtable不能将键和值设为null,否则运行时会报空指针异常错误
- HashMap线程不安全,Hashtable线程安全
对于集合的三种遍历方式删除:
1.普通for循环:可以删除注意每次删除之后索引要--
2.Iterator遍历:可以删除
不过要使用Iterator类中的remove方法,如果用List中的remove方法会报错
3.增强for循环foreach:不能删除
强制用List中的remove方法会报错
Java在序列化时不会实例化static变量和transient修饰的变量,因为static代表类的成员,transient代表对象的临时数据,被声明这两种类型的数据成员不能被序列化。
序列化的是对象,不是类,类变量不会被序列化。
Math.floor(x) 返回小于等于x的最接近整数,类型为double。
- final修饰变量,变量的引用(也就是指向的地址)不可变,但是引用的内容可以变(地址中的内容可变)。
- finalize方法,一个对象只能执行一次,只能在第一次进入被回收的队列,而且对象所属于的类重写了finalize方法才会被执行。第二次进入回收队列的时候,不会再执行其finalize方法,而是直接被二次标记,在下一次GC的时候被GC。
下列操作会使线程释放锁资源:
- wait()
- join()—–>join()底层就是调用wait()方法的,wait()释放锁资源,故join也释放锁资源。
- synchronized:用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这个段代码。
- volatile:用来确保将变量的跟新操作通知到其他线程,当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序。然而,在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比 synchronized关键字更轻量级的同步机制。
- serialize:Java 对象序列化为二进制文件。
在为传统面向对象语言的程序做单元测试的时候,经常用到mock对象。Mock对象通过反射数。但是,反射最大程度破坏了面向对象的封装特性。
面向对象设计方法主要特征的是继承。
java采用局部优先的思想。局部变量可以和成员变量相同,使用标识符调用时,优先使用局部变量。
jdbc的事务必须在一个数据库连接上完成。编程时必须去掉数据库的自动提交功能。当成功后调用commit,当失败后调用rollback。
单目运算符:+(正号),-(负号),++,–
算数运算符:+,-,*,/,%
移位运算符:<<,>>
关系运算符:>,<,>=,<=,==,!=
位运算符:&,|,~,^,
逻辑运算符:&&,||
三目运算符:表达式1?表达式2:表达式3;
赋值运算符:=命令javac-d参数的用途是:指定编译后类层次的根目录
常用ASCII码值:空格为32;数字0为48;“A”为65;“a”值为97。
Java文件与Bean所定义的类名可以不同,但一定要注意区分字母的大小写。
- 虚拟机中没有泛型,只有普通类和普通方法
- 所有泛型类的类型参数在编译时都会被擦除
- 创建泛型对象时请指明类型,让编译器尽早的做参数检查
ArrayList的构造函数总共有三个:
(1)ArrayList()构造一个初始容量为 10 的空列表。这种是默认创建大小为10的数组,每次扩容大小为1.5倍。(2)ArrayList(Collection<? extends E> c)构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。
(3)ArrayList(int initialCapacity)构造一个具有指定初始容量的空列表。这种是指定数组大小的创建,没有扩充。计算余弦值使用Math类的cos()方法
- toRadians()是将角度转换为弧度
- toDegrees()是将弧度转换为角度
包装类是针对基本数据类型的。
- Collection是java.util下的接口,它是各种集合结构的父接口
- Collections是java.util下的类,它包含有各种有关集合操作的静态方法
线程局部存储TLS(thread local storage)
- 解决多线程中的对同一变量的访问冲突的一种技术
- TLS会为每一个线程维护一个和该线程绑定的变量的副本
- Java平台的java.lang.ThreadLocal是TLS技术的一种实现
- 一个线程调用yield方法,可以使具有相同优先级线程获得处理器
- 在Java中,高优先级的可运行的线程会抢占低优先级线程的资源
- sleep与yield的其中一个区别:sleep给其他Thread运行不考虑优先级,而yield只给同等优先级或更高优先级运行。
三星题
ArrayList是基于数组实现的,所以查询快,增删慢;LinkedList是基于链表实现的,所以查找慢,增删快。
AOP和OOP都是一套方法论,也可以说成设计模式、思维方式、理论规则等等。
AOP不能替代OOP,OOP是obejct abstraction,而AOP是concern abstraction,前者主要是对对象的抽象,诸如抽象出某类业务对象的公用接口、报表业务对象的逻辑封装,更注重于某些共同对象共有行为的抽象,如报表模块中专门需要报表业务逻辑的封装,其他模块中需要其他的逻辑抽象
,而AOP则是对分散在各个模块中的共同行为的抽象,即关注点抽象。一些系统级的问题或者思考起来总与业务无关又多处存在的功能,可使用AOP,如异常信息处理机制统一将自定义的异常信息写入响应流进而到前台展示、行为日志记录用户操作过的方法等,这些东西用OOP来做,就是一个良好的接口、各处调用,但有时候会发现太多模块调用的逻辑大都一致、并且与核心业务无大关系,可以独立开来,让处理核心业务的人专注于核心业务的处理,关注分离了,自然代码更独立、更易调试分析、更具好维护。
核心业务还是要OOP来发挥作用,与AOP的侧重点不一样,前者有种纵向抽象的感觉,后者则是横向抽象的感觉,
AOP只是OOP的补充,无替代关系。同步是害怕在操作过程的时候被其他线程也进行读取操作,一旦是原子性的操作就不会发生这种情况。
因为一步到位的操作,其他线程不可能在中间干涉。另外三项都有读取、操作两个步骤,而X=1则是原子性操作。public class Test { public static void main(String[] args) { System.out.println(args[0]); } }
new Sub();在创造派生类的过程中首先创建基类对象,然后才能创建派生类。 创建基类即默认调用Base()方法,在方法中调用callName()方法,由于派生类中存在此方法,则被调用的callName()方法是派生类中的方法,此时派生类还未构造,所以变量baseName的值为null。 最终结果为:null1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
若采用命令行“java Test one two three”调用,则程序输出的结果为: one
解析:采用命令行“ java Test one two three ”调用,其中Test为调用的方法,而one two three则为Test方法里面main函数的参数。System.out.println(args[0]);表示输出第一个元素,故为one。
5. 管道( pipe ):管道是一种**半双工**的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
6. CGI不可移植,为某一特定平台编写的CGI应用只能运行于这一环境中。每一个CGI应用存在于一个由客户端请求激活的进程中,并且在请求被服务后被卸载。这种模式将引起很高的内存、CPU开销,而且在同一进程中不能服务多个客户。
7. volatile能保证数据的可见性,但不能完全保证数据的原子性,synchronized即保证了数据的可见性也保证了原子性。
8. 进入DEAD的线程,它还可以恢复,GC不会回收。
9. DBMS 中实现事务持久性的子系统是**恢复管理子系统**。
10. Java.Thread的方法resume()负责重新开始被suspend方法中断的线程的执行。
11. - HashMap实现了Map接口的,它的Key和Value都可以是null,但是Hashtable种,Key和Value都不能是null。
- ArrayList与LinkedList都实现了List接口,继承了AbstractList类。
12. 在**函数代码小,频繁调用**情况下适宜采用内联函数。
13. > - Java 中单实现通过 implements 关键字,多实现通过 extends 关键字
> - Java 中单继承通过 extends 关键字,没有多继承
> - 如果同时出现继承和实现,则必须先继承(extends)再实现(implements)
14. try的形式有三种:
- try-catch
- try-finally
- try-catch-finally
但catch和finally语句不能同时省略!
15. > 一个对象只要实现了Serilizable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过程,只要这个类实现了Serilizable接口,这个类的所有属性和方法都会自动序列化。
> 但某些情况下,这个类的有些属性需要序列化,而其他属性不需要被序列化,java 的transient关键字为我们提供了便利,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。
16. 饿汉式单例模式,在类创建时,就已经实例化完成,在调用getInstance()时,直接获取静态对象。obj1和obj2其实是一个对象,应该返回true。
17. - java中的字符串存储在字符串常量区,不会改变,发生改变是会新创建一个对象
- StringBuffer是线程安全的StringBuilder
- StringBuilder跟StringBuffer功能相同,区别是StringBuilder不是线程安全
- StringBuilder和StringBuffer底层都是以字符数组存放的,可以修改内容
18. J2EE中,当把来自客户机的HTTP请求委托给servlet时,会调用HttpServlet的**service**方法。
19. HttpServletResponse完成:设置http头标,设置cookie,设置返回数据类型,输出返回数据;
读取路径信息是HttpServletRequest做的。
20. - forward,服务器获取跳转页面内容传给用户,用户地址栏不变
- redirect,是服务器向用户发送转向的地址,redirect后地址栏变成新的地址
21. ThreadLocalMap中使用开放地址法来处理散列冲突,而HashMap中使用的是分离链表法。之所以采用不同的方式主要是因为:在ThreadLocalMap中的散列值分散得十分均匀,很少会出现冲突。并且ThreadLocalMap经常需要清除无用的对象,使用纯数组更加方便。
22. 父类没有**无参**的构造函数,所以子类需要在自己的构造函数中显式调用父类的构造函数。
23. - ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
- 对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
- 对于新增和删除操作add和remove,LinkedList比较占优势,因为ArrayList要移动数据。
- ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间。
24. - java不允许单独的方法,过程或函数存在,需要隶属于某一类中。
- Java的静态方法属于类的成员,实例方法属于对象的成员。
25. - 静态方法不能访问非静态变量
- 抽象类中的抽象方法不能有方法体
- 一个类中有多个类声明时,只能有一个public类
26. 一般用(System.in)创建InputStream对象,表示从标准输入中获取数据,用(System.out)创建OutputStream对象,表示输出到标准输出设备中。
27. > length 返回当前长度
> 如果字符串长度没有初始化长度大,capacity返回初始化的长度
> 如果append后的字符串长度超过初始化长度,capacity返回增长后的长度
> PS:
> StringBuffer和StringBuilder的默认大小为16
> ArrayList和LinkedList的默认大小10
28. 关于 Socket 通信编程,
- 服务器端通过new ServerSocket()创建TCP连接对象
- 服务器端通过TCP连接对象调用accept()方法创建通信的Socket对象
- 客户端通过new Socket()方法创建通信的Socket对象
29. JSP分页代码中,先取总记录数,得到总页数,最后显示本页的数据。
30. java在运行时才进行翻译指令。
31. 使用ObjectOutputStream和ObjectInputStream可以将对象进行传输。
## 四星题
1. 对于"==":
- 用于基本数据类型相互比较,比较二者的值是否相等。
- 用于引用数据类型相互比较,比较二者地址是否相等。
- 不能用于基本数据类型与引用型比较。
对于"equals":
- 不能用于基本数据类型比较(因为这是一个方法, 继承自object)。
- 用于进行对象的比较, 比较二者的引用地址是否相同。
2. 适配器模式 ,屏蔽远程对象,通过适配器模拟本地对象,本地对象称之为存根。与动态链接技术有关。
3. ThreadLocalMap使用开放定址法解决hash冲突,HashMap使用链地址法解决hash冲突。
4. 没有final修饰的变量相加后会被自动提升为int型,与目标类型byte不相容,需要强制转换(向下转型)。
5. 关于OutOfMemoryError,
> - java.lang.OutOfMemoryError: PermGen space 增加-XX:MaxPermSize这个参数的值的话,这个问题通常会得到解决。
> - java.lang.OutOfMemoryError: Requested array size exceeds VM limit当你正准备创建一个超过虚拟机允许的大小的数组时,这条错误将会出现。
> - java.lang.OutOfMemoryError: Java heap space 一般情况下解决这个问题最快的方法就是通过-Xmx参数来增加堆的大小。
6. JDK提供的用于并发编程的同步器:
- Semaphore
- CyclicBarrier
- CountDownLatch
7. > Java语言中的异常处理包括声明异常、抛出异常、捕获异常和处理异常四个环节。
>
> - throw用于抛出异常。
> - throws关键字可以在方法上声明该方法要抛出的异常,然后在方法内部通过throw抛出异常对象。
> - try是用于检测被包住的语句块是否出现异常,如果有异常,则抛出异常,并执行catch语句。
> - cacth用于捕获从try中抛出的异常并作出处理。
> - finally语句块是不管有没有出现异常都要执行的内容。
8. - run()方法用来执行线程体中具体的内容
- start()方法用来启动线程对象,使其进入就绪状态
- sleep()方法用来使线程进入睡眠状态
- suspend()方法用来使线程挂起,要通过resume()方法使其重新启动
9. - Semaphore:类,控制某个资源可被同时访问的个数;
- ReentrantLock:类,具有与使用synchronized方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大;
- Future:接口,表示异步计算的结果;
- CountDownLatch: 类,可以用来在一个线程中等待多个线程完成任务的类。
10. Hibernate 中 get()和load() 的区别:
- get()采用立即加载方式,而load()采用延迟加载; get()方法执行的时候,会立即向数据库发出查询语句, 而load()方法返回的是一个代理(此代理中只有一个id属性),只有等真正使用该对象属性的时候,才会发出 sql语句
- 如果数据库中没有对应的记录,get()方法返回的是null。而load()方法出现异常ObjectNotFoundException
11. hashCode()方法和equals()方法的作用其实是一样的,在Java里都是用来对比两个对象是否相等一致。
那么equals()既然已经能实现对比的功能了,为什么还要hashCode()呢?因为重写的equals()里一般比较的比较全面比较复杂,这样效率就比较低,而利用hashCode()进行对比,则只要生成一个hash值进行比较就可以了,效率很高。
那么hashCode()既然效率这么高为什么还要equals()呢? 因为hashCode()并不是完全可靠,有时候不同的对象他们生成的hashcode也会一样(生成hash值得公式可能存在的问题),所以hashCode()只能说是大部分时候可靠,并不是绝对可靠,
所以我们可以得出:
- equals()相等的两个对象他们的hashCode()肯定相等,也就是用equals()对比是绝对可靠的。
- hashCode()相等的两个对象他们的equal()不一定相等,也就是hashCode()不是绝对可靠的
12. SimpleDateFormat是线程不安全的。
13. 在java中,我们可以用异常(Exception)来抛出一些并非错误的消息,但这样比直接从函数返回一个结果要更大的系统开销。
14. java用(监视器)机制实现了进程之间的同步执行。
15. jre 判断程序是否执行结束的标准是**所有的前台线程执行完毕**。
16. 我们在执行`URL u =new URL("http://www.123.com");`这句话的时候确实要抛出异常,但是这个异常属于IOException,不管网址是否存在,最后都会返回该网址的一个链接,打印出来就是该网址。
17. 关于JSP生命周期的叙述,
- JSP会先解释成Servlet源文件,然后编译成Servlet类文件
- 每当用户端运行JSP时,jsp service()方法都会运行一次
18. 有关java的引用类型,
- 对于一个对象来说,只要有强引用的存在,它就会一直存在于内存中
- 如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收
- 如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存
- 一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的空间
## 五星题
1. 一般关系数据模型和对象数据模型之间有以下对应关系:表对应类,记录对应对象,表的字段对应类的属性。
2. 实现GBK编码字节流到UTF-8编码字节流的转换:
dst=new String(src,"GBK").getBytes("UTF-8");
3. 对于线程而言,start是让线程从new变成runnable。run方法才是执行体的入口。
但是在Thread中,run方法是个空方法,没有具体实现。
Bground(新类)继承了Thread,但是没有重写run方法,那么调用run方法肯定是无输出。
4. Java数据库连接库JDBC用到**桥接模式** 。
5. > SpringMVC的原理:
> SpringMVC是Spring中的模块,它实现了mvc设计模式的web框架,首先用户发出请求,请求到达SpringMVC的前端控制器(DispatcherServlet),前端控制器根据用户的url请求处理器映射器查找匹配该url的handler,并返回一个执行链,前端控制器再请求处理器适配器调用相应的handler进行处理并返回给前端控制器一个modelAndView,前端控制器再请求视图解析器对返回的逻辑视图进行解析,最后前端控制器将返回的视图进行渲染并把数据装入到request域,返回给用户。
> DispatcherServlet作为springMVC的前端控制器,负责接收用户的请求并根据用户的请求返回相应的视图给用户。
> 实现业务操作时在service层。
6. 一个 try 块可能有多个 catch 块。若如此,则执行第一个匹配块。即Java虚拟机会把实际抛出的异常对象依次和各个catch代码块声明的异常类型匹配,如果异常对象为某个异常类型或 其子类的实例,就执行这个catch代码块,不会再执行其他的 catch代码块 。
7. 鲁棒性(Robust,即健壮性)
Java在编译和运行程序时,都要对可能出现的问题进行检查,以消除错误的产生。它提供自动垃圾收集来进行内存管理,防止程序员在管理内存时容易产生 的错误。通过集成的面向对象的例外处理机制,在编译时,Java揭示出可能出现但未被处理的例外,帮助程序员正确地进行选择以防止系统的崩溃。另外, Java在编译时还可捕获类型声明中的许多常见错误,防止动态运行时不匹配问题的出现。
8. ```java
public class Base
{
private String baseName = "base";
public Base()
{
callName();
}
public void callName()
{
System. out. println(baseName);
}
static class Sub extends Base
{
private String baseName = "sub";
public void callName()
{
System. out. println (baseName) ;
}
}
public static void main(String[] args)
{
Base b = new Sub();
}
}JVM内存区:程序计数器、虚拟机栈、本地方法栈、堆、方法区(包括常量池)。
- 我们可以直接调用Thread对象中的run方法,但就起不到多线程的目的了。
- ThreadLocal用于创建线程的本地变量,该变量是线程之间不共享的
Java中字节流的流对象:
- FileInputStream
- BufferedInputStream
- PushbackInputStream
- ByteArrayInputStream
- LinkedBlockingQueue是一个基于节点链接的可选是否有界的阻塞队列,不允许null值。
- LinkedBlockingQueue是一个线程安全的阻塞队列,实现了先进先出等特性。
- PriorityQueue是一个无界队列,不允许null值,入队和出队的时间复杂度是O(log(n))。
- PriorityQueue是不同于先进先出队列的另一种队列。每次从队列中取出的是具有最高优先权的元素。ConcurrentLinkedQueue是一个基于链接节点的无界线程安全队列,该队列的元素遵循FIFO原则。
Java一律采用Unicode编码方式,每个字符无论中文还是英文字符都占用2个字节。
程序运行时异常由Java虚拟机自动进行处理。
依赖注入的动机就是减少组件之间的耦合度,使开发更为简洁。
- 依赖注入能够独立开发各组件,然后根据组件间关系进行组装
- 依赖注入提供使用接口编程
- 依赖注入指对象在使用时动态注入
有一个源代码,只包含import java.util.* ; 这一个import语句,能访问java/util目录下的所有类,不能访问java/util子目录下的所有类。
在有除法存在的代码处,抛不抛出异常均可。
- 一般而言,PreparedStatement比Statement执行效率更高
- PreparedStatement会预编译SQL语句
- Statement每次都会解析/编译SQL,确立并优化数据获取路径
weblogic中开发消息Bean时的persistent与non-persisten的差别:
- persistent方式的MDB可以保证消息传递的可靠性,也就是如果EJB容器出现问题而JMS服务器依然会将消息在此MDB可用的时候发送过来。
- non-persistent方式的消息将被丢弃。
Iterator支持从源集合中安全地删除对象,只需在 Iterator 上调用 remove() 即可。
由于构造器的名字必须与类名相同,而匿名类没有类名,所以匿名类不能有构造器。
- 使用匿名内部类时,必须继承一个类或实现一个接口
- 匿名内部类由于没有名字,因此不能定义构造函数
- 匿名内部类中不能含有静态成员变量和静态方法
Object类的部分方法:
- notify()
- notifyAll()
- wait()
PS:
不是恶意诽谤牛客网,实在是题目质量得不到保证。有的题目错,有的答案错,甚至你在刷Java题目时动不动就来个C语言的题目,很是让人无语。牛客网的题目似乎是用户传上去的,只丢个答案在那里,没有官方解答,题目下方评论区的确有大神做解答,但鱼龙混杂,也有辣鸡在装X的(随意粘贴别处的知识点,最可恶的是解答是错的,这种人是真的恶心)。一星题与五星题的区别并不是你想的那样,仅仅是多选题数量的增多而已,估计这也是安卓端无法进行题目筛选的原因,因为根本没用。还有,强烈建议牛客网将Java题库中的Swing、AWT有关的题目去除,现在还有鬼在用这个东西啊?至于题目涉及的范围倒还好,都是基础知识,建议多加一些框架相关的题目,毕竟现在的开发都是会用到框架的。 刷了3天的题库,400多道题,刷完立刻看解析,边刷题边写笔记。然而并没有什么卵用,考试题全是Spring,一脸懵逼,蓝瘦、香菇。