- Math.*
ceil:大于等于 x,并且与它最接近的整数。
floor:小于等于 x,且与 x 最接近的整数。
Math.ceil(d1)
ceil 方法上有这么一段注释:If the argument value is less than zero but greater than -1.0, then the result is negative zero
如果参数小于0且大于-1.0,结果为 -0
Math.floor(d1)
ceil 和 floor 方法 上都有一句话:If the argument is NaN or an infinity or positive zero or negative zero, then the result is the same as the argument,意思为:如果参数是 NaN、无穷、正 0、负 0,那么结果与参数相同,
- 关于Collecttion
- 数据类型的转换
数据类型的转换,分为自动转换和强制转换。自动转换是程序在执行过程中 “ 悄然 ” 进行的转换,不需要用户提前声明,一般是从位数低的类型向位数高的类型转换;
byte,short,char-> int -> long -> float -> double
- 代码执行顺序
1
2
3
4
5
6
7
8
9
10
11
12
131. class StaticStuff
2 {
3. static int x = 10;
4.
5. static { x += 5; }
6.
7. public static void main(String args[])
8. {
9. System.out.println(“x = ” + StaticStuff .x);
10. }
11. static
12. {x /= 3; }
13.}
代码编译并执行,输出结果 x = 5.
正常类的加载顺序:静态变量/静态代码块 -> main方法 -> 非静态变量/代码块 -> 构造方法
静态代码块与静态变量的执行顺序同代码定义的顺序;非静态变量与代码块的执行顺序同代码执行顺序
- switch()的参数类型
switch语句后的控制表达式只能是short、char、int、long整数类型和枚举类型,不能是float,double和boolean类型。String类型是java7开始支持。
- 输出结果构造块 构造块 静态块 构造块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public class B
{
public static B t1 = new B();
public static B t2 = new B();
{
System.out.println("构造块");
}
static
{
System.out.println("静态块");
}
public static void main(String[] args)
{
B t = new B();
}
}
- yield
一个线程调用yield方法,可以使具有相同优先级线程获得处理器
yiled方法属于高风亮节的行为,这个坑位我不上了,后面跟我同级别的先上厕所。这样比较好记!
- 多态的作用()
提高可重用性
扩展代码模块
没有隐藏细节,隐藏细节应该是封装干的事情吧
- session 和 cookie
session用来表示用户会话,session对象在服务端维护,一般tomcat设定session生命周期为30分钟,超时将失效,也可以主动设置无效;
cookie存放在客户端,可以分为内存cookie和磁盘cookie。内存cookie在浏览器关闭后消失,磁盘cookie超时后消失。当浏览器发送请求时,将自动发送对应cookie信息,前提是请求url满足cookie路径; 3.可以将sessionId存放在cookie中,也可以通过重写url将sessionId拼接在url。因此可以查看浏览器cookie或地址栏url看到sessionId;
- 顺序
1 | public class Example extends Thread{ |
run main
好坑
因为Example的run方法里面休眠了100ms,在当今电脑计算性能过剩的时代,如果是多线程启动,main方法肯定会打印出了main。
为啥是runmain而不是mainrun呢?
因为启动线程是调用start方法。
把线程的run方法当普通方法,就直接用实例.run()执行就好了。
没有看到start。所以是普通方法调用。
- 顺序
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
31public class HelloB extends HelloA
{
public HelloB()
{
}
{
System.out.println("I’m B class");
}
static
{
System.out.println("static B");
}
public static void main(String[] args)
{
new HelloB();
}
}
class HelloA
{
public HelloA()
{
}
{
System.out.println("I’m A class");
}
static
{
System.out.println("static A");
}
}
当涉及到继承时,按照如下顺序执行:
1、执行父类的静态代码块
static {
System.out.println(“static A”);
}
输出:static A
2、执行子类的静态代码块
static {
System.out.println(“static B”);
}
输出:static B
3、执行父类的构造代码块
{
System.out.println(“I’m A class”);
}
输出:I’m A class
4、执行父类的构造函数
public HelloA() {
}
输出:无
5、执行子类的构造代码块
{
System.out.println(“I’m B class”);
}
输出:I’m B class
6、执行子类的构造函数
public HelloB() {
}
输出:无
- 要导入java/awt/event下面的所有类
只能是import java.awt.event.*
- 正确的方法声明
protected abstract void f1(); // 抽象方法只可以被public 和 protected修饰;
private void f1() {}
static final void fq(){} // static final 可以表达在一起来修饰方法,表示是该方法是静态的不可重写的方法
public final void f1() {}
- 运算符>>和>>>
表示右移,如果该数为正,则高位补0,若为负数,则高位补1。如:int i=15; i>>2的结果是3,移出的部分将被抛弃。
转为二进制的形式可能更好理解,0000 1111(15)右移2位的结果是0000 0011(3),0001 1010(18)右移3位的结果是0000 0011(3)。
表示是带符号的右移:按照二进制把数字右移指定数位,符号位为正补零,符号位负补一,低位直接移除。
表示无符号的右移:按照二进制把数字右移指定数位,高位直接补零,低位移除。
- catch块和finally块不可以同时省略
- final
final修饰符,可以修饰类,方法,变量,不能修饰接口
final修饰的类不可以被继承
final修饰的方法不可以被覆盖
final修饰的变量为常量。只能赋值一次
一般final化的成员变量也会静态化
- 代码判断
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19class Person {
String name = "No name";
public Person(String nm) {
name = nm;
}
}
class Employee extends Person {
String empID = "0000";
public Employee(String id) {
empID = id;
}
}
public class Test {
public static void main(String args[]) {
Employee e = new Employee("123");
System.out.println(e.empID);
}
}
编译报错
父类没有无参的构造函数,所以子类需要在自己的构造函数中显式调用父类的构造函数,
- abstract
抽象类中有抽象方法,需要被实现,不能实例化。
可以被继承,如果不继承,里面的抽象方法就没意思了。
子类不一定为抽象类,可以是,也可以不是。
抽象类不仅可以被继承,还可以直接拿来使用的,当然,这个使用是拿来声明,而不是实例化,因为抽象类不能实例化,但可以声明使用。就像接口一样。
可以被抽象类继承
- Object类
A synchronized Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。
B C D 都是Object类中的方法
notify(): 是唤醒一个正在等待该对象的线程。
notifyAll(): 唤醒所有正在等待该对象的线程。
E sleep 是Thread类中的方法
wait 和 sleep的区别:
wait指线程处于进入等待状态,形象地说明为“等待使用CPU”,此时线程不占用任何资源,不增加时间限制。
sleep指线程被调用时,占着CPU不工作,形象地说明为“占着CPU睡觉”,此时,系统的CPU部分资源被占用,其他线程无法进入,会增加时间限制。
- HashMap和Hashtable
HashMap和Hashtable都是典型的Map实现
Hashtable在实现Map接口时保证了线程安全性,而HashMap则是非线程安全的。所以,Hashtable的性能不如HashMap,因为为了保证线程安全它牺牲了一些性能。因此选项B错误
Hashtable不允许存入null,无论是以null作为key或value,都会引发异常。而HashMap是允许存入null的,无论是以null作为key或value,都是可以的。
- final
1.final修饰变量,则等同于常量
2.final修饰方法中的参数,称为最终参数。
3.final修饰类,则类不能被继承
4.final修饰方法,则方法不能被重写。
5.final 不能修饰抽象类
6.final修饰的方法可以被重载 但不能被重写
- Java中参数传递
在方法中,修改一个基础类型的参数不会影响原始参数值
在方法中,改变一个对象参数的引用不会影响到原始引用
1 | public static void main(String []args){ |
在方法中,修改一个对象的属性会影响原始对象参数
1 | public static void main(String []args){ |
在方法中,修改集合和Maps的元素不会影响原始集合参数
集合和Maps都是对象 ,
- java object
Object中没有copy方法
clone可以
- final、finally、finalize三个关键字的区别
final:可用来定义变量、方法传入的参数、类、方法。
finally:只能跟在try/catch语句中,并且附带一个语句块,表示最后执行。
finalize:是垃圾回收器操作的运行机制中的一部分,进行垃圾回收器操作时会调用finalize方法,因为finalize方法是object的方法,所以每个类都有这个方法并且可以重写这个方法,在这个方法里实现释放系统资源及其他清理工作,JVM不保证此方法总被调用。
- sblj
class类是Object的派生类
每个类都使用Object类作为超类,而final修饰的类不能被继承
String类是一个final类
Class类可以装载其它类
- 线程共享
私有:java虚拟机栈,程序计数器,本地方法栈
共享:java堆,方法区
- 线程安全
线程同步:喂,SHE
喂(Vector)
S(Stack)
H(hashtable)
E(enumeration)
- 变量及其范围
类的成员变量包括实例变量和类变量(静态变量),成员方法包括实例方法和类方法(静态方法)
类变量(静态变量)用关键字static声明
方法中的局部变量在方法被调用加载时开始入栈时创建,方法入栈创建栈帧包括局部变量表操作数栈,局部变量表存放局部变量,并非在执行该方法时被创建
局部变量在使用前必须被初始化
- /
Java中/是取整,别和数学里的搞混了
- 不属于JVM堆内存中的区域
常量池
jvm堆分为:新生代(一般是一个Eden区,两个Survivor区),老年代(old区)。
常量池属于 PermGen(方法区)
- Integer,string
String s = “abc”:通过字面量赋值创建字符串。则将栈中的引用直接指向该字符串,如不存在,则在常量池中生成一个字符串,再将栈中的引用指向该字符串
String s = “a”+“bc”:编译阶段会直接将“a”和“bc”结合成“abc”,这时如果方法区已存在“abc”,则将s的引用指向该字符串,如不存在,则在方法区中生成字符串“abc”对象,然后再将s的引用指向该字符串
String s = “a” + new String(“bc”):栈中先创建一个”a”字符串常量,再创建一个”bc”字符串常量,编译阶段不会进行拼接,在运行阶段拼接成”abc”字符串常量并将s的引用指向它,效果相当于String s = new String(“abc”),只有’+’两边都是字符串常量才会在编译阶段优化
Integer的范围是-128~127,如果超出范围的话会新建一个对象,否则就是使用内存中的那个对象。
String str=new String(“abc”)和String str=”abc”的字符串“abc”都是存放在堆中,而不是存在栈中。
1 | public class Test{ |
- java程序内存泄露的最直接表现
程序抛内存溢出的Exception
java是自动管理内存的,通常情况下程序运行到稳定状态,内存大小也达到一个 基本稳定的值
但是内存泄露导致Gc不能回收泄露的垃圾,内存不断变大.
最终超出内存界限,抛出OutOfMemoryExpection
FullGC 是老年代内存空间不足的时候,才会触发的,老年代一般是生命周期较长的对象或者大对象,频繁的 FullGC 不会可能会影响程序性能(因为内存回收需要消耗CPU等资源),但是并不会直接导致内存泄漏。
JVM奔溃的可能是内存溢出引起的,也可能是其他导致 JVM崩溃的操作,例如设置了错误的JVM参数等。
- java 类加载器
1)Bootstrap ClassLoader
负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类
2)Extension ClassLoader
负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包
3)App ClassLoader
负责记载classpath中指定的jar包及目录中class
4)Custom ClassLoader
属于应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader
- 在WEB开发中实现会话跟踪实现
有四种方法可以实现会话跟踪技术:URL重写、隐藏表单域、Cookie、Session。
1).隐藏表单域:,非常适合步需要大量数据存储的会话应用。
2).URL 重写:URL 可以在后面附加参数,和服务器的请求一起发送,这些参数为名字/值对。
3).Cookie:一个 Cookie 是一个小的,已命名数据元素。服务器使用 SET-Cookie 头标将它作为 HTTP
响应的一部分传送到客户端,客户端被请求保存 Cookie 值,在对同一服务器的后续请求使用一个
Cookie 头标将之返回到服务器。与其它技术比较,Cookie 的一个优点是在浏览器会话结束后,甚至
在客户端计算机重启后它仍可以保留其值
4).Session:使用 setAttribute(String str,Object obj)方法将对象捆绑到一个会话