- JVM的程序计数器1和虚拟机栈2是线程隔离的,方法区3和堆4是共享的。
- 1:当前线程执行到字节码的那个位置,执行本地方法时,为空;2:存储局部变量,操作数栈,动态链接,方法出口等,一个方法->一个栈帧??,一个线程->一个栈;3:JVM加载的所有类信息(名称、方法信息、字段信息等),静态变量,常量,编译器编译后的代码等;4:new出来的java对象,为对象的实例分配内存。
- package包:必须是源文件非注释语句的第一条。一个源文件只能指定一个包,所以只能包含一条package语句。
- %取余操作只适用于整型、
- 关于类的静态成员变量
- 该类的对象共享其静态成员变量的值
- 静态成员变量可被该类的所有方法访问
- 该类的静态方法只能访问该类的静态成员变量
- 该类的静态数据成员变量的值可修改,常量成员不可修改。
- jvm堆内存溢出OOM(“Out of Memory”)异常? JVM堆有持久代Permanent Space 和 Heap Space。持久代中一般存放 静态数据成员,类、方法等,与GC要回收的Java对象关系不大。heap space,分为老年代Old Generation 和年轻带Young GC。Young Generation,执行YoungGC分为1个Eden区+2个Survivor区。中经历多次回收依旧存活的对象会复制到Old Generation中,这里执行FullGC,这里存放的对象生命周期都较长。Old GC 溢出:设置的内存参数Xmx过小或程序的内存泄露及使用不当问题, 循环上万次的字符串处理、创建上千万个对象、在一段代码内申请上百M甚至上G的内存。持久代溢出:动态加载了大量Java类而导致溢出。通常由于持久代设置过小,动态加载了大量Java类而导致溢出 。
- ConcurrentHashMap 使用segment来分段和管理锁,segment继承自ReentrantLock,因此ConcurrentHashMap使用ReentrantLock来保证线程安全,而不是synchronized关键字。
【错---Array.asList方法返回java.util.ArrayList对象。】返回的列表是Arrays.ArrayList类型,并不是java.util.ArrayList。
class Enclosingone { //非静态内部类 public class InsideOne {} //静态内部类 public static class InsideTwo{} } public class inertest{ public static void main(String args []){ EnclosingOne eo = new EnclosingOne(); InsideOne obj11 = eo.new InsideOne();//非静态内部类对象 Enclosingone.InsideOne obj1 = new Enclosingone().new InsideOne();//非静态内部类对象(与上两句等价) Enclosingone.InsideTwo obj2 = new Enclosingone.InsideTwo();//静态内部类对象 //Outer.Inner a=new Outer().new Inner()(非静态,先有Outer对象才能有属性) // 静态:Outer.Inner a=new Outer.Inner()要把Outer.Inner看做一个整体 } }
String s = "hello"; String t = "hello"; char c [ ] = {'h','e','1','1','o'}; System.out.println(s.equals (t)); //true s和t指向内存常量区的同一个字符串 ; System.out.println(t.equals (c));//false 一个返回字符串,一个返回对象 ; System.out.println(s==t);// true s和t指向内存常量区的同一个字符串 ; System.out.println(t.equals (new String ("hello")));//true equals用于比较两个对象的值是否相同,和内存地址无关
byte b1=1,b2=2,b3,b6,b8; final byte b4=4,b5=6,b7;// final成员变量必须在声明的时候初始化或者在构造器中初始化,否则就会报编译错误。 //没有在声明时初始化final变量的称为空白final变量(blank final variable),它们必须在构造器中初始化,或者调用this()初始化 b3=(b1+b2); /*语句1 错,自动转为int,所以正确写法为b3=(byte)(b1+b2);或者将b3定义为int;*/ b6=b4+b5; /*语句2 对,b4、b5为final类型,不会自动提升,所以和的类型视左边变量类型而定,即b6可以是任意数值类型*/ b8=(b1+b4); /*语句3 错,虽然b4不会自动提升,但b1仍会自动提升,所以结果需要强转,b8=(byte)(b1+b4);*/ b7=(b2+b5); /*语句4,错,final变量不可以被再次赋值*/ System.out.println(b3+b6);
- forward和redirect的描述:
- forward时,浏览器不知道服务器发送的内容是从何处来,浏览器地址栏中还是原来的地址
- 执行执行redirect时,服务器端告诉浏览器重新去请求地址
- forward是内部重定向,redirect是外部重定向
A派生出子类B,B派生出子类C,并且在java源代码中有如下声明: A a0=new A();//Java虽是单继承,但是继承具有传递性,多态的三种表现形式:继承重写,重载,向上转型。 A a1=new B();//向上转型。 A a2=new C();//创建了一个B的对象,并将A的对象变量(引用)指向B的对象,即父类引用指向子类对象,是可以的。
- 抽象类是不能实例化,实例化必将加载类,因为不知道抽象方法的方法体大小,所以不能实例化。
- final类,不希望被继承被扩展或者被修改。final方法是可以被继承的,但是不可以被覆盖。
- 采用MVC即是分层模式来设计web应用程序,【可维护性强、可扩展性强、代码重复少】可以清晰发现问题,增强可维护性,而且面向接口的编程使程序的可扩展性增强,通过MVC统一的处理请求,可以减少代码的重复,但是代码量,这个不好说。
- servlet中init,service,destroy方法
Servlet是线程不安全的,在Servlet类中可能会定义共享的类变量,这样在并发的多线程访问的情况下,不同的线程对成员变量的修改会引发错误。定义局部变量,而不是类变量或者对象的成员变量。由于方法中的局部变量是在栈中,彼此各自都拥有独立的运行空间而不会互相干扰,因此才做到线程安全。
- 自动拆装箱(JDK1.5+)
- 基本型和基本型封装型进行“==”运算符的比较,基本型封装型将会自动拆箱变为基本型后再进行比较,因此Integer(0)会自动拆箱为int类型再进行比较,显然返回true;
- 两个Integer类型进行“==”比较,如果其值在-128至127,那么返回true,否则返回false, 这跟Integer.valueOf()的缓冲对象有关,这里不进行赘述。
- 两个基本型的封装型进行equals()比较,首先equals()会比较类型,如果类型相同,则继续比较值,如果值也相同,返回true
- 基本型封装类型调用equals(),但是参数是基本类型,这时候,先会进行自动装箱(基本型变成对应的基本封装类型),再进行3中的比较。
int a=257;
Integer b=257;
Integer c=257;
Integer b2=57;
Integer c2=57;
System.out.println(a==b);//true
//System.out.println(a.equals(b)); //编译出错,基本型不能调用equals() 封装类型可以调用
System.out.println(b.equals(257.0));//false 类型不一样
System.out.println(b==c);//false 越界
System.out.println(b2==c2);//true
- public Method[] getDeclaredMethods() 返回类或接口声明的所有方法,包括public, protected, default (package) 访问和private方法的Method对象,但不包括继承的方法。???没懂
- public Method[] getMethods()返回类的所有public方法,包括其继承类的公用方法,当然也包括它所实现接口的方法。
- Child extends Parent,那么一定有
- 如果Child是interface,那么Parent必然是interface
如果Child是interface,那么Parent必然是interface
如果Child是class,并且没有显示声明任何构造函数,那么此时仍然会调用Parent的构造函数