多态实现
父类的引用指向子类对象
生产者消费者手写
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中去,
不仅从代码上解耦和,而且需要更换数据库时,不需要进行代码的重新编译。