常见问题
13常见问题
编译期:java在javac命令下编译成class文件,运行期:java在JVM加载运行class文件。
jdk是java开发工具包(开发环境和jre) jre,java运行环境,是JVM和java核心类库的总称
“src”文件夹用于存放用户编写的Java源文件;“bin”文件夹用于存放Eclipse自动编译生成的class文件。
JVM中类的装载是由类加载器(ClassLoader)和它的子类来实现的,Java中的类加载器是一个重要的Java运行时系统组件,它负责在运行时查找和装入类文件中的类。
由于Java的跨平台性,经过编译的Java源程序并不是一个可执行程序,而是一个或多个类文件。当Java程序需要使用某个类时,JVM会确保这个类已经被加载、连接(验证、准备和解析)和初始化。类的加载是指把类的.class文件中的数据读入到内存中,通常是创建一个字节数组读入.class文件,然后产生与所加载类对应的Class对象。加载完成后,Class对象还不完整,所以此时的类还不可用。当类被加载后就进入连接阶段,这一阶段包括验证、准备(为静态变量分配内存并设置默认的初始值)和解析(将符号引用替换为直接引用)三个步骤。最后JVM对类进行初始化,包括:1)如果类存在直接的父类并且这个类还没有被初始化,那么就先初始化父类;2)如果类中存在初始化语句,就依次执行这些初始化语句。
类的加载是由类加载器完成的,类加载器包括:根加载器(BootStrap)>扩展加载器(Extension)>系统加载器(System)>用户自定义类加载器(java.lang.ClassLoader的子类)。从Java 2(JDK 1.2)开始,类加载过程采取了父亲委托机制(PDM)。PDM更好的保证了Java平台的安全性,在该机制中,JVM自带的Bootstrap是根加载器,其他的加载器都有且仅有一个父类加载器。类的加载首先请求父类加载器加载,父类加载器无能为力时才由其子类加载器自行加载。JVM不会向Java程序提供对Bootstrap的引用。
Java工作区间:
栈:存放对象引用、局部变量,另外需注意的是栈中存放变量的值是可以共享的,优先在栈中寻找是否有相同变量的值,如果有直接指向这个值,如果没有则另
外分配。
堆:存放new出来的对象, 堆中的对象生命周期的管理由Java虚拟机的垃圾回收机制GC进行回收和统一管理。
方法区:类的基本信息和类的方法(所有对象共享一份方法)、静态区(存放static修饰的变量和static块)、常量池,类加载的时候jvm通过clasloader或者其他类
加载器把这个类转换成字节码文件,类的方法只有要执行的时候才会占用内存。方法区在类编译期类加载就绑定的。
常量池:final修饰的变量、byte short int long char boolean的包装类(Byte、Short、Integer、Long要求范围在-128到127,否则在堆中创建对象)、string类。(float、double包装类没实现这个技术),常量池避免了对象的重复创建,
实现了复用。
例1:如Integer i1=33;Integer i2=33;i1=i2为true,因为自动装箱实现的技术,利用Integer调用valueOf()方法,这个方法当值是-128到127的时候,这个实例是处于常量池中,超过这个范围的值就在堆中创建实例对象。
Integer a = 33;
Integer b = 33;
Integer c = 128;
Integer d = 128;
System.out.println(a == b);
System.out.println(c == d);
结果:
true
false
例2:
String str1 = "abcd";
String str2 = new String("abcd");
String str3="abcd";
str1==str2;//false str1==str3;(true)
例3:
public static final String A = "ab"; // 常量Apublic static final String B = "cd"; // 常量B
String s = A + B; // 将两个常量用+连接对s进行初始化
String t = "abcd";
s==t;类编译期间就确定了A和B的值, 等同于:String s="ab"+"cd";
例4:
public static final String A; // 常量A
public static final String B; // 常量B
static {
A = "ab";
B = "cd";
}
public static void main(String[] args) {
// 将两个常量用+连接对s进行初始化 String s = A + B;
String t = "abcd";
s == t(faslse)jvm编译类文件,是编译好了再初始化static块,所以虽然static块也是编译期间绑定的,s也只有运行期才能确定值了,这个时候的A和B只是变量引用不
能确定他的值是多少
例5:
String hello = "Hello", lo = "lo";
String c="Hellolo";
String s=("Hello"+lo).inter();
c==s;(true)常量池不一定是编译期间产生的,调用string的intern方法可以在运行期间产生
-
break、continue、return区别
break:跳出循环 continue:跳出本次循环进入下次循环 return:结束return所在的方法体
Static 、final 、private 定义的方法在子类不会重写,只是隐藏了父类的方法,自己重新定义了一个新的方法
基本数据类型分类(4类8种)
* 整数型
* byte 占一个字节 -128到127
* short 占两个字 -2^15~2^15-1
* int 占四个字节 -2^31~2^31-1
* long 占八个字节 -2^63~2^63-1
* 浮点型
* float 占四个字节 -3.403E38~3.403E38 单精度
* double 占八个字节-1.798E308~1.798E308 双精度
* 字符型
* char 占两个字节 0~65535
* 布尔型
* boolean
* boolean理论上是占八分之一个字节, 但是,它的大小不是明确指定的.
boolean的大小JVM规范并没有指定
byte b1 = 3;
* byte b2 = 4;
* byte b3 = b1 + b2; 会发生错误,运算3+4,精度出错,改成(byte)(b1+b2)
类型转换常见问题汇总
1) 强制转换时的精度丧失和溢出。
2) 数值运算时的自动转换。
自动转型
自增自减不会自动转型
+-*/%位运算符(&|~^>><<>>>)
运算时自动转型成高精度:
有double 转换成double再运算
有float 转换成float 再运算
有long 转换成long 再运算
否则都转换成int再运算
下面实例中b会先寻找byte方法,如果没有就先转型成高精度基本类型,再没有就自动装箱成Byte包装类
public void t(Byte b){syso(“BYTE”)}
public void t(Integer b){syso(“INTEGER”)}
public void t(byte b){syso(“byte”)}
public void t(int b){syso(“int”)}
public void t(long b){syso(“long”)}
Public static void main(String[] args){byte b = 34; t(b)}
3.long型要在数值后加l或L float型要在后面加F或f
八进制以0开头 十六进制以0X或0x开头
- javaBean规范
满足如下规范的类,建议初学者把所有的类满足这个规范
- 有package
- 有默认构造器
- 实现序列化接口
- 可能有getset方法
java反射
- 类的定义
1.1 java中每个类都是Class类的一个实例,这个实例只有一个,c1、c2叫做这个F类的类类型
方式一:Class c1=F.class;
方式二:Class c2=f.getClass();
方式三:Class c3=Class.forName("F");
1.2.创建这个F类的实例
方式一:F f = new F();
方式二:F f=(F)c1.newInstance();//需要有无参构造
2.Class类
编译时刻加载类是静态加载类,运行时加载类是动态加载类。Class.forName()是动态加载类。这个类中保存了F类的所有信息。
3) byte、char、short转换为int的问题
int直接量可以直接赋值给byte、char和short,只要不超过其表示范围。
byte、char、short三种类型参与运算时,先一律转换成int类型再进行运算。
4)转义字符:’\n’ ‘\r’ ‘\\’ ‘\’’ ‘\”’
5)短路逻辑:&& || 和&| 区别: &&当第一个为假就不会判断第二个,||当第一个为真就不判断第二个,&和|不管真假都会判断两个条件。
如何判断一个数是质数
求n的平方根m,判断n是否能被2到m整除,能表示不是质数
int double默认0 ;String默认null;char默认null;数组默认null;局部变量需要初始化再使用
正则表达式:要表达一个特殊字符如表达一个.号,用\\.表示
方法前面写上@Test 没有参数 没有返回值 表示每个方法都能独立执行
-
如何新建Maven项目:
javaEE界面中右键新建maven project,勾上第一个create,然后next,输入第一个组名和项目名,结束,最后打开target包里pom.xml,点击第二个dependencies 导入相应的jar包。
-
回车符和换行符的区别
回车符 \r 换行符 \n 回车是到本行的左边,换行是回到该行的正下边。
6、做项目时以服务器或数据库的时间为准。
-
数据库中单引号会自动转化成大写,双引号则区分大小写。
同时,双引号和单引号的区别,在一个字符串中,如果里面还有字符串,则要单双引号包含使用,不能同时使用相同引号,在转移字符中如果要显示引号,而不是把他当做字符串的引号使用,就要用转义字符。
preparedStatement的setint double float方法不能插入null值,但是数据库中字段又是能有null值得,解决这的办法是用pre的setObject
junit的测试方法:在无返回值、无参数的方法前写上@Test表示测试,写上@Before表示在执行所有test方法之前先执行这个方法。
8.密码加密
MessageDigest md= MessageDigest.getInstance("MD5");
//加密处理
byte[] output
=md.digest(src.getBytes());
//return new String(output);
//利用Base64转换成字符串结果
String ret
=Base64.encodeBase64String(output);
md5加密不可逆,base64是把字节数组转换成字符,也可以把字符解码成字节数组。
9.数据库的主键问题
数据库主键是一个不重复的至,可以使用数据库自带的办法,如mysql的自增,但是这样会存在性能问题,数据库生成一个值还要再从这里取出拿给服务器,一般都使用UUID算法,生成的值不同
9.在设计时 一定要对数据进行检验,比如对入口的参数在表示层、业务层等检验空。 三层结构设计对异常要注意,考虑异常情况的发生,自己能处理或者跑出去。name==null||name.trem().isEmpty()进行判断
10 mysql中遇到的问题
给主键设置了自增,或则给字段设置了默认值,在isnert可以选择其他字段插入或者插入整个表的时候使用default表示插入的数据
timestamp类型的字段
默认非空,默认值是‘0000-00-00 00:00:00’
可以给字段设置default current_timestamp 根据当前时间自动初始化
default current_timestamp on update current_timestamp 根据当前时间自动初始化并且自动跟新时间
不能同时给两个字段设置current_timestamp,
timestamp 默认允许为 “非空”(not null by default), 如果你在定义“ts TIMESTAMP DEFAULT NULL” 是非法的。 可以指定为空 null ,要指定字段为空,使用“ts TIMESTAMP NULL default null" ,这时可以在添加语句改变默认值为null了。
11 类的方法不要返回一个可变引用类型,如public Date getDay(){return hiryDay;}因为返回的Date类型是可变的,调用date的setTime()可更改,违反了封装性,可以rerturn hirday.clone(),返回一个克隆的副本数据。
12 java方法中的传值:按值传递和引用传递
按值传递:不会影响基本类型和布尔类型的值
private int a=3;
public void set(int b){
b=b*10;
}
调用set(a)时a的值还是3,按内存分析,传给set方法的值是a的一份拷贝,所以不会更改a的值
按引用传递
private Emp e1;
public void set1(Emp e){
e.setS(0);
}
public void set2(Emp e){
e= new Emp();
}
set(e1);e1的值会改变,按内存分析,方法中的值是e1的一份拷贝,代表这e引用指向的地址,也就更改了e1的内容
set2(e1);e1的值不会改变,按内存分析,方法中的值是e1的一份拷贝,代表这e引用指向的地址,但是e又指向了另一个对象,原对象e1不会改变。
13. I/O 以流的方式处理数据,而 NIO 以块的方式处理数据。NIO全部使用缓存技术,读写都是通过缓存。

浙公网安备 33010602011771号