This is my blog
by
名称 | 取值范围 | 存储空间 |
---|---|---|
字节(Byte) | $-2^7$ ~ $2^7-1$ -128 ~ 127 |
1个字节 |
短整数(short) | $-2^15$ ~ $2^15-1$ -32768 ~ 32767 |
2个字节 |
整数(int) | $-2^31$ ~ $2^31-1$ -2147483648 ~ 2147483647 |
四个字节 |
长整数(long) | $-2^63$ ~ $2^63-1$ | 8个字节 |
单精度(float) | $2^-149$ ~ $2^128-1$ | 4个字节 |
双精度(double) | $2^-1074$ ~ $2^1024-1$ | 8个字节 |
float d1 = 423432423f;
float d2 = d1 + 1;
if(d1 == d2){
System.out.println("d1==d2");
}else{
System.out.println("d1!=d2");
}
BigDecimal
package com.lin.interview;
import java.util.Random;
/**
* 30-100的随机整数
*/
public class RandomSample {
//方法1
public Integer randomInt1(){
int min = 30;
int max = 101;
int result = new Random().nextInt(max - min) + min;
return result;
}
//方法2
public Integer randomInt2(){
int min = 30;
int max = 101;
int result = (int)(Math.random()*(max-min))+min;
return result;
}
public static void main(String[] args) {
System.out.println(new RandomSample().randomInt1());
System.out.println(new RandomSample().randomInt2());
}
}
package com.lin.interview;
/**
* 1-1000内的质数
*/
public class PrimeNumber {
public static void main(String[] args) {
for (int i = 2; i <= 1000; i++) {
boolean flag = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
flag = false;
break;
}
}
if (flag) {
System.out.print(i + " ");
}
}
}
}
相同点 | 不同点 |
---|---|
都是上层的抽象 | 抽象类可包含方法的实现 接口则只能包含方法的声明 |
不能被实例化 | 继承类只能继承一个抽象类 实现类可以实现多个接口 |
都可以包含抽象方法 | 抽象级别 接口>抽象类>实现类 |
作用不同: 接口用于约束程序行为 继承则用于代码复用 |
注意:JDK8以上版本,接口可以有default方法,包含方法实现
Exception | Error |
---|---|
可以是可被控制或不可控制 | 总是不可控制 |
表示一个由程序员导致的错误 | 经常用于表示系统错误或底层资源错误 |
应该在应用程序级被处理 | 如果可能的话,应该在系统级被捕获 |
String s1="abc";
String s2="def";
String s3="abc"+"def";
String s4="abcdef";
String s5=s2+"def";
String s6=new String("abc");
System.out.println(s1==s2);//true 比较地址
System.out.println(s3==s4);//true 比较地址
System.out.println(s4==s5);//false 实际使用中s2为引用类型,编译期间无法确定数值,运行时确定,s5为新的地址与s4不同
System.out.println(s4.equals(s5));//true 比较字符内容
System.out.println(s1==s6);//false new出的对象,存放地址不同
String | StringBuilder | StringBuffer | |
---|---|---|---|
执行速度 | 最差 | 其次 | 最高 |
线程安全 | 线程安全 | 线程安全 | 线程不安全 |
使用场景 | 少量字符串操作 | 多线程环境下的大量操作 | 单线程环境下的大量操作 |
List | Set | |
---|---|---|
允许重复 | 是 | 否 |
是否允许null | 是 | 否 |
是否有序 | 是 | 否 |
常用类 | ArrayList LinkedList |
HashSet LinkedHashSet TreeSet |
ArrayList | LinkedList | |
---|---|---|
存储结构 | 基于动态数组 | 基于链表 |
遍历方式 | 连续读取 | 基于指针 |
适用场景 | 大数据量读取 | 频繁新增、插入 |
HashSet | TreeSet | |
---|---|---|
排序方式 | 不能保证顺序 | 按预置规则排序 |
底层存储 | 基于HashMap | 基于TreeMap |
底层实现 | 基于Hash表实现 | 基于二叉树实现 |
package com.lin.interview.sorter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ListSorter {
public static void main(String[] args) {
List<Employee> emps = new ArrayList<Employee>();
emps.add(new Employee("张三",33,10009f));
emps.add(new Employee("李四",40,7800f));
emps.add(new Employee("王五",50,6533f));
Collections.sort(emps, new Comparator<Employee>() { //排序
@Override
public int compare(Employee o1, Employee o2) { //内部匿名方法
if((o1.getSalary()-o2.getSalary())<0 && (o1.getSalary()-o2.getSalary())>-1){
return -1;
}
if((o1.getSalary()-o2.getSalary())>0 && (o1.getSalary()-o2.getSalary())<1){
return 1;
}
// 当前为升序
return (int)(o1.getSalary()-o2.getSalary());
// 当前为降序
//return (int)(o2.getSalary()-o1.getSalary());
}
});
System.out.println(emps);
}
}
public class Employee implements Comparable<Employee>{
@Override
public int compareTo(Employee o) {
return this.getAge().compareTo(o.getAge()); //compareTo 1 前面大于后面 -1 后面大于前面
}
}
public class SetSorter{
public static void main(String[] args) {
//直接调用
TreeSet<Employee> emps = new TreeSet<Employee>();
}
}
输入流 | 输出流 | |
---|---|---|
字节流 | InputStream FileInputStream BufferedInputStream |
OutputStream FileOutputStream BufferedOutputStream |
字符流 | Reader FileReader InputStreamReader BufferedReader |
Writer FileWriter OutputStreamWriter BufferedWriter |
package com.lin.interview;
import java.io.*;
public class FileCopy {
public static void main(String[] args) {
//1. 利用Java IO
File source = new File("D:\\开发资源\\spring-framework-4.2.4.RELEASE-dist.zip");
File target = new File("D:\\开发资源\\target\\spring-framework-4.2.4.RELEASE-dist.zip");
InputStream ipt = null;
OutputStream opt = null;
try {
ipt = new FileInputStream(source);
opt = new FileOutputStream(target);
byte[] buf = new byte[1024];
int byteRead;
while ((byteRead = ipt.read(buf)) != -1) {
opt.write(buf, 0, byteRead);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
ipt.close();
opt.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//2. FileChannel 实现文件复制
//3. Commons IO组件实现文件复制
//FileUtils.copyFile(Source,Target);
}
}
package com.lin.interview.thread;
import java.util.Random;
public class ThreadSample1 {
public static void main(String[] args) {
//五条线程
Runnerl r1 = new Runnerl();
r1.setName("张三");
Runnerl r2 = new Runnerl();
r2.setName("李四");
Runnerl r3 = new Runnerl();
r3.setName("王五");
r1.start();
r2.start();
r3.start();
//****************
}
}
/**
* 第一种 Thread
*/
class Runnerl extends Thread{
@Override
public void run(){
Integer speed = new Random().nextInt(10)+1;
for (int i=1;i<=1000;i++){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.getName()+"已前进"+(i*speed)+"米");
}
}
}
package com.lin.interview.thread;
import java.util.Random;
public class ThreadSample2 {
public static void main(String[] args) {
Thread r1 = new Thread(new Runner2());
r1.setName("张三");
Thread r2 = new Thread(new Runner2());
r2.setName("李四");
Thread r3 = new Thread(new Runner2());
r3.setName("王五");
r1.start();
r2.start();
r3.start();
}
}
/**
* 第二种
* 第二种与第一种 底层一致
* 开发中更推荐 第二种,接口实现 ,更加友好
*/
class Runner2 implements Runnable {
@Override
public void run() {
Integer speed = new Random().nextInt(10) + 1;
for (int i = 1; i <= 100; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "已前进" + (i * speed) + "米");
}
}
}
package com.lin.interview.thread;
import java.util.Random;
import java.util.concurrent.*;
public class ThreadSample3 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建一个固定长度的线程池
ExecutorService threadPool = Executors.newFixedThreadPool(3);
Runner3 r1 = new Runner3();
Runner3 r2 = new Runner3();
Runner3 r3 = new Runner3();
r1.setName("张三");
r2.setName("李四");
r3.setName("王五");
Future<Long> result1 = threadPool.submit(r1);
Future<Long> result2 = threadPool.submit(r2);
Future<Long> result3 = threadPool.submit(r3);
System.out.println(result1.get());
System.out.println(result2.get());
System.out.println(result3.get());
}
}
/**
* 第三种
* JDK 1.5以上
* 高级做法
*/
class Runner3 implements Callable<Long>{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public Long call() throws Exception {
Integer speed = new Random().nextInt(10) + 1;
Long distince = 0l;
for (int i = 1; i <= 100; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
distince = (long)(i*speed);
System.out.println(this.getName() + "已前进" + (i * speed) + "米");
}
return distince;
}
}
主线程(守护线程)、回收线程(JVM回收资源)
多线程编程中,多线程访问资源,资源没有及时释放,资源交叉引用,导致程序假死。
//线程死锁例子
package com.lin.interview;
public class DeadLock {
private static String fileA = "A文件";
private static String fileB = "B文件";
public static void main(String[] args) {
new Thread(){ //线程1
public void run(){
while(true) {
synchronized (fileA) {//打开文件A,线程独占
System.out.println(this.getName() + ":文件A写入");
synchronized (fileB) {
System.out.println(this.getName() + ":文件B写入");
}
System.out.println(this.getName() + ":所有文件保存");
}
}
}
}.start();
new Thread(){ //线程2
public void run(){
while(true) {
synchronized (fileB) {//打开文件B,线程独占
System.out.println(this.getName() + ":文件B写入");
synchronized (fileA) {
System.out.println(this.getName() + ":文件A写入");
}
System.out.println(this.getName() + ":所有文件保存");
}
}
}
}.start();
}
}
面试常考,JVM内存中通用回答,五大区域
GC是一把双刃剑,一方面程序开发提供便捷,另一方面不断地对内存进行监听等,增加JVM负担,降低程序执行效率。
Java存在内存泄漏
内存泄漏:一个不再程序被使用的对象、变量还在内存占用空间 —
Object中存在一个对象复制,这里的复制指浅复制
package com.lin.interview.clone;
import java.io.*;
public class Dancer implements Cloneable,Serializable{
private String name;
private Dancer partner;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Dancer getPartner() {
return partner;
}
public void setPartner(Dancer partner) {
this.partner = partner;
}
//深复制 采用序列化方式
public Dancer deepClone() throws IOException, ClassNotFoundException {
//序列化,将内存中的对象序列化为字节数组
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
//反序列化,将字节数组转回为对象,同时完成深复制的任务
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (Dancer)ois.readObject();
}
public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
Dancer d1 = new Dancer();
d1.setName("刘明");
Dancer d2 = new Dancer();
d2.setName("吴明霞");
d1.setPartner(d2);
System.out.println("Partner:" + d2.hashCode());
//浅复制
Dancer shallow = (Dancer) d1.clone();
System.out.println("浅复制:"+shallow.getPartner().hashCode());
//深复制
Dancer deep = (Dancer)d1.deepClone();
System.out.println("深复制:"+deep.getPartner().hashCode());
}
}
tags: