多态实现
父类的引用指向子类对象
生产者消费者手写
import java.util.*;
class Storage {
private final int MAX_SIZE=100;
private LinkedList list = new LinkedList();
public void produce(int num) {
synchronized(list) {
while(list.size()+num>MAX_SIZE) {
System.out.println("暂时不能执行生产任务");
try {
list.wait();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
for (int i=0; i<num; i++) {
list.add(new Object());
}
System.out.println("仓库中有产品"+list.size());
list.notifyAll();
}
}
public void consume(int num) {
synchronized(list) {
while(list.size()<num) {
System.out.println("暂时不能执行消费任务");
try {
list.wait();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
for (int i=0; i<num; i++) {
list.remove();
}
System.out.println("仓库中有产品"+list.size());
list.notifyAll();
}
}
}
class Producer extends Thread {
private int num;
public Storage storage;
public Producer(Storage storage) {
this.storage=storage;
}
public void setNum(int num) {
this.num=num;
}
public void run() {
storage.produce(num);
}
}
class Consumer extends Thread {
private int num;
public Storage storage;
public Consumer(Storage storage) {
this.storage=storage;
}
public void setNum(int num) {
this.num=num;
}
public void run() {
storage.consume(num);
}
}
public class Test {
public static void main(String[] args) {
Storage storage = new Storage();
Producer p1 = new Producer(storage);
Producer p2 = new Producer(storage);
Producer p3 = new Producer(storage);
Producer p4 = new Producer(storage);
Producer p5 = new Producer(storage);
Consumer c1 = new Consumer(storage);
Consumer c2 = new Consumer(storage);
Consumer c3 = new Consumer(storage);
p1.setNum(10);
p2.setNum(20);
p3.setNum(30);
p4.setNum(40);
p5.setNum(50);
c1.setNum(60);
c2.setNum(20);
c3.setNum(100);
c1.start();
c2.start();
c3.start();
p1.start();
p2.start();
p3.start();
p4.start();
p5.start();
}
} SQL查询语句手写SELECT 列名称 FROM 表名称Mybatis批量查询手写
HashTable:
底层数组+链表实现,无论key还是value都不能为null,线程安全,
实现线程安全的方式是在修改数据时锁住整个HashTable,效率低,
ConcurrentHashMap做了相关优化。
HashMap:
底层数组+链表实现,可以存储null键和null值,线程不安全。
ConcurrentHashMap:
底层采用分段的数组+链表实现,线程安全。
通过把整个Map分成N个Segment,可以提供相同的线程安全,但是效率提升N倍。
为什么要使用ConcurrentHashMap
在并发编程中使用HashMap可能导致程序死循环,而线程安全的HashTable效率又非常低下,
基于以上两个原因,便有了ConcurrentHashMap的登场机会。
HashMap在并发执行put操作时会引起死循环,是因为多线程会导致HashMap的Entry链表
形成环形数据结构,一旦形成环形数据结构,Entry的next节点永远不为空,就会产生死循环
获取Entry。
HashTable容器在并发环境下效率低下的原因是所有访问HashTable的线程都必须竞争同一把锁。
ConcurrentHashMap使用锁分段技术,将数据分成一段一段地存储,然后给每一段数据配一把锁,
当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。
内存泄漏的情况有哪些
内存泄漏的定义:一个不再被程序使用的对象或变量还在内存中占有存储空间。
1、静态集合类,如HashTable、LinkedList等,如果这些容器为静态的,那么他们的
生命周期与程序一致,则容器中的对象在程序结束之前不能被释放,从而造成内存泄漏。
2、数据库连接,网络连接,IO连接等,当不再使用连接时需要调用close方法来释放连接。
只有连接关闭时,垃圾回收器才会回收对应的对象。否则,如果在访问数据库的过程中,
对Connection、Statement或ResultSet不显性地关闭,将会造成大量的对象无法被回收,从而
引起内存泄漏。
3、变量不合理的作用域。一般而言,如果一个变量的定义的作用范围大于其使用范围,很可能造成
内存泄漏。
4、内部类持有外部类
如果一个外部类的实例对象的方法返回了一个内部类的实例对象,这个内部类对象被长期引用了,
即使那个外部类实例对象不再被使用,但由于内部类持有外部类的实例对象,这个外部类对象将不会被垃圾回收,这也会造成内存泄露。
5、改变哈希值,
当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段了,
否则,对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,
即使在contains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回找不到对象的结果,
这也会导致无法从HashSet集合中单独删除当前对象,造成内存泄露
classpath,path的区别
path是windows查找.exe文件的路径;classpath是jvm查找.class文件的路径
JVM运行过程
GC机制讲一讲 可能还有,记不清了
线程池,阻塞队列
http ,https区别
非对称加密和对称加密
对称加密:加密密钥和解密密钥使用相同的密码体制。
非对称加密:使用不同的加密密钥和解密密钥。
数据加密标准DES属于对称密钥密码体制。
DES的保密性仅取决于对密钥的保密,而算法是公开的。
公钥加密,私钥解密
如何设计一个服务器(socket相关)
IDEA常用快捷键:
1、智能提示:Ctrl+Space
Alt+Enter:快速修复错误
2、代码生成
Alt+Insert
3、Ctrl+/:注释
如何使得浏览器加载请求可以稳定打到后台而不使用浏览器缓存(请求中加一个随机值参数)
spring事务写在哪一部分,为什么不写在DAO,Controller层
数据库驱动为什么使用反射调用不直接new
为什么一定要使用反射呢?因为反射是运行时根据全限定类名动态生成的Class对象,
可以把这个全类名写在xml或者properties中去,
不仅从代码上解耦和,而且需要更换数据库时,不需要进行代码的重新编译。

京公网安备 11010502036488号