Java面试题-java基础,
Java面试题-java基础,
ArrayList
内部使用数组的形式实现了存储,利用数组的下标进行元素的访问,因此对元素的随机访问速度非常快。
因为是数组,所以ArrayList在初始化的时候,有初始大小10,插入新元素的时候,会判断是否需要扩容,扩容的步长是0.5倍原容量,扩容方式是利用数组的复制,因此有一定的开销;
作者:艾尔欧唯伊
链接:https://www.jianshu.com/p/5b3aa50aa388
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
- LinkedList
- 内部使用双向链表的结构实现存储,LinkedList有一个内部类作为存放元素的单元,里面有三个属性,用来存放元素本身以及前后2个单元的引用,另外LinkedList内部还有一个header属性,用来标识起始位置,LinkedList的第一个单元和最后一个单元都会指向header,因此形成了一个双向的链表结构。
作者:艾尔欧唯伊
链接:https://www.jianshu.com/p/5b3aa50aa388
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
equals()和==的区别
- ”==”除了比较基本数据之外都是比较的内存地址
- “equals”除了没有没有重写equals方法的类之外都是比较的内容
https://www.cnblogs.com/lingyujuan/p/6491883.html
hashcode
定义:hashCode方法实际上返回的就是Java中的集合里对象存储的物理地址- NIO与IO
- 面向流与面向缓冲
- 阻塞与非阻塞
https://www.cnblogs.com/snailclimb/p/9086334.html
https://zhuanlan.zhihu.com/p/27296046
https://blog.csdn.net/z69183787/article/details/77102198
Selector
https://blog.csdn.net/dd864140130/article/details/50299687- SelectionKey key = channel.register(selector, Selectionkey.OP_READ);
- SelectionKey介绍
一个SelectionKey键表示了一个特定的通道对象和一个特定的选择器对象之间的注册关系。
key.attachment(); //返回SelectionKey的attachment,attachment可以在注册channel的时候指定。
key.channel(); // 返回该SelectionKey对应的channel。
key.selector(); // 返回该SelectionKey对应的Selector。
key.interestOps(); //返回代表需要Selector监控的IO操作的bit mask
key.readyOps(); // 返回一个bit mask,代表在相应channel上可以进行的IO操作。
ByteBuffer
https://www.cnblogs.com/legend_sun/p/3696748.html- ByteBuffer 以及flip,clear及rewind区别
http://xiachaofeng.iteye.com/blog/1416634
nio(1):buffer
nio(2):channel
Java NIO(6): Selector
- ByteBuffer 以及flip,clear及rewind区别
HashMap
- Java HashMap 是非线程安全的。
- java.util.Hashtable 类,此类是线程安全的
- java.util.Collections.synchronizedMap() 方法包装 HashMap object,得到线程安全的Map,并在此Map上进行操作
https://blog.csdn.net/itzhangdaopin/article/details/78720139
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法。 在对象被从内存中清理出去之前,做必要的清理工作。
Java 序列化
Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。
将序列化对象写入文件之后,可以从文件中读取出来,并且对它进行反序列化,也就是说,对象的类型信息、对象的数据,还有对象中的数据类型可以用来在内存中新建对象。
http://www.runoob.com/java/java-serialization.html
import java.io.*;
public class DeserializeDemo
{
public static void main(String [] args)
{
Employee e = null;
try
{
FileInputStream fileIn = new FileInputStream("D://tmp/employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
e = (Employee) in.readObject();
in.close();
fileIn.close();
}catch(IOException i)
{
i.printStackTrace();
return;
}catch(ClassNotFoundException c)
{
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
System.out.println("Deserialized Employee...");
System.out.println("Name: " + e.name);
System.out.println("Address: " + e.address);
System.out.println("SSN: " + e.SSN);
System.out.println("Number: " + e.number);
}
}
import java.io.*;
public class SerializeDemo
{
public static void main(String [] args)
{
Employee e = new Employee();
e.name = "Reyan Ali";
e.address = "Phokka Kuan, Ambehta Peer";
e.SSN = 11122333;
e.number = 101;
try
{
FileOutputStream fileOut =
new FileOutputStream("D://tmp/employee.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(e);
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in /tmp/employee.ser");
}catch(IOException i)
{
i.printStackTrace();
}
}
}
public class Employee implements java.io.Serializable
{
public String name;
public String address;
public transient int SSN;
public int number;
public void mailCheck()
{
System.out.println("Mailing a check to " + name
+ " " + address);
}
}
String s=new String(“xyz”)究竟创建String Object分为两种情况:
1.如果String常量池中,已经创建”xyz”,则不会继续创建,此时只创建了一个对象new String(“xyz”);
2.如果String常量池中,没有创建”xyz”,则会创建两个对象,一个对象的值是”xyz”,一个对象new String(“xyz”)。多线程
https://blog.csdn.net/qq_22239675/article/details/78722290实现多线程的三种方式
https://www.cnblogs.com/songshu120/p/7966314.html- 继承Thread类创建线程
- 通过Runnable接口创建线程
- 通过Callable和Future创建线程
volatile
https://www.cnblogs.com/dolphin0520/p/3920373.html- Java内存模型规定所有的变量都是存在主存当中(类似于前面说的物理内存),每个线程都有自己的工作内存(类似于前面的高速缓存)。线程对变量的所有操作都必须在工作内存中进行,而不能直接对主存进行操作。并且每个线程不能访问其他线程的工作内存。
- 执行线程必须先在自己的工作线程中对变量i所在的缓存行进行赋值操作,然后再写入主存当中。而不是直接将数值10写入主存当中。
- 当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。
https://www.cnblogs.com/dolphin0520/p/3920373.html(讲的很清
线程间通信 https://www.cnblogs.com/leipDao/p/8310974.html
Java程序中启动一个线程是用run()还是start()?
- https://blog.csdn.net/lai_li/article/details/53070141?locationNum=13&fps=1
- start方法:
通过该方法启动线程的同时也创建了一个线程,真正实现了多线程。无需等待run()方法中的代码执行完毕,就可以接着执行下面的代码。此时start()的这个线程处于就绪状态,当得到CPU的时间片后就会执行其中的run()方法。这个run()方法包含了要执行的这个线程的内容,run()方法运行结束,此线程也就终止了。
- run方法:
通过run方法启动线程其实就是调用一个类中的方法,当作普通的方法的方式调用。并没有创建一个线程,程序中依旧只有一个主线程,必须等到run()方法里面的代码执行完毕,才会继续执行下面的代码,这样就没有达到写线程的目的。
- run方法:
守护进程
- JVM内部的实现是如果运行的程序只剩下守护线程的话,程序将终止运行,直接结束。所以守护线程是作为辅助线程存在的,
https://blog.csdn.net/cbjcry/article/details/70154647
- JVM内部的实现是如果运行的程序只剩下守护线程的话,程序将终止运行,直接结束。所以守护线程是作为辅助线程存在的,
- ThreadLocal
https://www.cnblogs.com/WuXuanKun/p/5827060.html - sleep和wait
- sleep() 和 wait() 的区别就是调用sleep方法的线程不会释放对象锁,而调用wait() 方法会释放对象锁
- https://blog.csdn.net/xyh269/article/details/52613507
- 可重入锁
synchronized和ReentrantLock都是可重入锁,可重入性在我看来实际上表明了锁的分配机制:基于线程的分配,而不是基于方法调用的分配。举个简单的例子,当一个线程执行到某个synchronized方法时,比如说method1,而在method1中会调用另外一个synchronized方法method2,此时线程不必重新去申请锁,而是可以直接执行方法method2。
看下面这段代码就明白了:
复制代码
class MyClass {
public synchronized void method1() {
method2();
}
public synchronized void method2() {
}
}
Java 8新特性
- Lambda 表达式(参见https://www.cnblogs.com/franson-2016/p/5593080.html)
Lambda表达式的语法
基本语法:
(parameters) -> expression
或
(parameters) ->{ statements; }
下面是Java lambda表达式的简单例子:
// 1. 不需要参数,返回值为 5
() -> 5
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
https://blog.csdn.net/qq_18416057/article/details/70143475
* 方法引用
https://www.cnblogs.com/xiaoxi/p/7099667.html
* 函数式接口
https://www.cnblogs.com/runningTurtle/p/7092632.html
*
相关文章
- 暂无相关文章
用户点评