(1)有以下一段代码,请选择其运行结果
0 2 2
public
class
Spike
{
public
static
void
main(String[] args)
{
Counter a =
new
Counter();
System.out.println(a.increment());
System.out.println(a.anotherIncrement());
Counter b =
new
Counter();
System.out.println(b.increment());
}
}
class
Counter
{
private
static
int
count =
0
;
public
int
increment()
{
return
count++;
}
public
int
anotherIncrement()
{
return
++count;
}
}
1、先要注意,count是静态变量,被所有对象共享
2、接着要明白count++与++count的区别,前者是先赋值后相加,后者是先相加后赋值
3、第一次a.increment()里的count是先赋值后相加,所以会先返回0,接着后相加,此时静态变量count为1。
4、第二次a.anotherIncrement()里的count是先相加后赋值,所以相加后count为2,接着返回2,此时静态变量count为2。
5、第三次a.increment()里的count是先赋值后相加,所以会先返回2,接着后相加,此时静态变量count为3。
(2)
同步是害怕在操作过程的时候被其他线程也进行读取操作,一旦是原子性的操作就不会发生这种情况。
因为一步到位的操作,其他线程不可能在中间干涉。都有读取、操作两个步骤的就需要来同步,而X=1则是原子性操作。
(3)
HttpServlet容器响应Web客户请求流程如下:
1)Web客户向Servlet容器发出Http请求;
2)Servlet容器解析Web客户的Http请求;
3)Servlet容器创建一个HttpRequest对象,在这个对象中封装Http请求信息;
4)Servlet容器创建一个HttpResponse对象;
5)Servlet容器调用HttpServlet的service方法,这个方法中会根据request的Method来判断具体是执行doGet还是doPost,把HttpRequest和HttpResponse对象作为service方法的参数传给HttpServlet对象;
6)HttpServlet调用HttpRequest的有关方法,获取HTTP请求信息;
7)HttpServlet调用HttpResponse的有关方法,生成响应数据;
8)Servlet容器把HttpServlet的响应结果传给Web客户。
doGet() 或 doPost() 是创建HttpServlet时需要覆盖的方法.
(4)
throws:写在方法声明之后,表示方法可能抛出异常,调用者需要处理这个异常。
throw:写在方法体中,表示方法一定会抛出一个异常,要么try...catch处理,要么throws抛出。
(5)以下 b 的值是: byte b = (byte)129;
-127
解析:因为byte是有符号单字节整形,所以存储数字范围是[-128·127]
而127[01111111]+1==128[10000000]。
为什么呢?
因为科学家定义数字的时候是一个环,最大的数字后面就是最小,这样才可以把[0·255]分配给[-128·127]。
底层就是补码的概念。
也就是127,-128,-127,-126...如果数到129那就是继续往下数2个,即-127。
(6)共享数据的所有访问一定要作为临界区,用synchronized标识,这样保证了所有的对共享数据的操作都通过对象锁的机制进行控制。
(7)下面程序的输出结果是 3423
public class TestDemo {
public static String output =
""
;
public static void foo(int i){
try
{
if
(i == 1){
throw
new
Exception();
}
}
catch
(Exception e){
output +=
"2"
;
return
;
}finally{
output +=
"3"
;
}
output +=
"4"
;
}
public static void main(String[] args) {
foo(0);
foo(1);
System.out.println(output);
}
}
解析:
解题要点:
1、try中没有抛出异常,则catch语句不执行,如果有finally语句,则接着执行finally语句,继而接着执行finally之后的语句;
2、try中抛出异常,有匹配的catch语句,则catch语句捕获,如果catch中有return语句,则要在finally执行后再执行;
(8)
1.静态代码块 2.构造代码块3.构造方法的执行顺序是1>2>3;明白他们是干嘛的就理解了。
1.静态代码块:是在类的加载过程的第三步初始化的时候进行的,主要目的是给类变量赋予初始值。
2.构造代码块:是独立的,必须依附载体才能运行,Java会把构造代码块放到每种构造方法的前面,用于实例化一些共有的实例变量,减少代码量。
3.构造方法:用于实例化变量。
1是类级别的,2、3是实例级别的,自然1要优先23.
在就明白一点:对子类得主动使用会导致对其父类得主动使用,所以尽管实例化的是子类,但也会导致父类的初始化和实例化,且优于子类执行。
(9)下面的代码会输出什么
prints:3
public
class
Test{
static
{
int
x=
5
;
}
static
int
x,y;
public
static
void
main(String args[]){
x--;
myMethod( );
System.out.println(x+y+ ++x);
}
public
static
void
myMethod( ){
y=x++ + ++x;
}
}
解析:
1.JVM加载class文件时,就会执行静态代码块,静态代码块中初始化了一个变量x并初始化为5,由于该变量是个局部变量,静态代码快执行完后变被释放。
2.申明了两个静态成员变量x,y,并没有赋初值,会有默认出值,int类型为0,
3.执行x--操作,变量单独进行自增或自减操作x--和--x的效果一样,此时x变为了-1
4.调用MyMethod()方法,在该方法中对x和y进行计算,由于x和y都是静态成员变量,所以在整个类的生命周期内的x和y都是同一个
5.y=x++ + ++x可以看成是y=(x++)+(++x),当++或者--和其它变量进行运算时,x++表示先运算,再自增,++x表示先自增再参与运算
所以就时x为-1参与运算,然后自增,x此时为0,++x后x为1,然后参与运算,那么y=-1+1就为0,此时x为1
6.执行并打印x+y + ++x运算方式和第5步相同,最后计算结果就为3.
(10)关键字的坑
关键字常见的坑:
true、false、null都不是关键字,而是常量
goto、const、是保留的关键字
(11)
Lanbda表达式的主要作用就是代替匿名内部类的繁琐语法, 它由三部分组成:
(1) 形参列表。形参列表允许省略形参类型。如果形参列表中只有一个参数,甚至连形参列表的圆括号也可以省略。
(2) 箭头(→)。必须通过英文中画线和大于符号组成。
(3)代码块。如果代码块只包含一条语句,Lambda表达式允许省略代码块的花括号,那么那条语句就不要用花括号表示语句结束。Lambda代码块只有一条return语句,甚至可以省略return关键字。Lambda表达式需要返回值,而它的代码块中仅有一套省略了return的语句。Lambda表达式会自动返回这条语句的值。