sleep()方法不会释放锁,wait()方法会释放锁;
sleep()方法主要用于暂停线程的执行,wait()方法主要用于线程之间的交互/通信;
sleep() 方法执行完成后,线程会自动苏醒;wait() 方法被调用后,线程不会自动苏醒,需要其他线程调用同一个对象上的 notify()或者 notifyAll() 方法。或者也可以使用 wait(long timeout) 超时后线程会自动苏醒;
sleep()方法是Thread类的静态方法,wait()方法是Object类的本地方法;
wait()、notify()方法必须写在同步方法/同步代码块中,是为了防止死锁和永久等待,使线程更安全,而sleep()方法没有这个限制。
如果想要详细了解这个问题,可以参考我的另一篇文章——Java并发常见面试题(二)。
如果想要详细了解这个问题,可以参考我的另一篇文章——Java并发常见面试题(三)。
自上到下依次是:
如果想要详细了解这个问题,可以参考这篇文章——OSI七层模型详解。
是否面向连接 :UDP 在传送数据之前不需要先建立连接。而 TCP 提供面向连接的服务,在传送数据之前必须先建立连接,数据传送结束后要释放连接;
是否是可靠传输:远地主机在收到 UDP 报文后,不需要给出任何确认,并且不保证数据不丢失,不保证是否顺序到达。TCP 提供可靠的传输服务,TCP 在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制。通过 TCP 连接传输的数据,无差错、不丢失、不重复、并且按序到达;
是否有状态 :这个和上面的“是否可靠传输”相对应。TCP 传输是有状态的,这个有状态说的是 TCP 会去记录自己发送消息的状态比如消息是否发送了、是否被接收了等等。为此 ,TCP 需要维持复杂的连接状态表。而 UDP 是无状态服务,简单来说就是不管发出去之后的事情了;
传输效率 :由于使用 TCP 进行传输的时候多了连接、确认、重传等机制,所以 TCP 的传输效率要比 UDP 低很多;
传输形式 : TCP 是面向字节流的,UDP 是面向报文的;
首部开销 :TCP 首部开销(20 ~ 60 字节)比 UDP 首部开销(8 字节)要大;
是否提供广播或多播服务 :TCP 只支持点对点通信,UDP 支持一对一、一对多、多对一、多对多。
@Autowired 是 Spring 提供的注解,@Resource 是 JDK 提供的注解。
Autowired 默认的注入方式为byType(根据类型进行匹配),@Resource默认注入方式为 byName(根据名称进行匹配)。
当一个接口存在多个实现类的情况下,@Autowired 和@Resource都需要通过名称才能正确匹配到对应的 Bean。Autowired 可以通过 @Qualifier 注解来显式指定名称,@Resource可以通过 name 属性来显式指定名称。
如果想要详细了解这个问题,可以参考这篇文章——Spring Bean的生命周期。
线程是否安全: HashMap 是非线程安全的,Hashtable 是线程安全的,因为 Hashtable 内部的方法基本都经过synchronized 修饰。(如果你要保证线程安全的话就使用 ConcurrentHashMap 吧!);
效率: 因为线程安全的问题,HashMap 要比 Hashtable 效率高一点。另外,Hashtable 基本被淘汰,不要在代码中使用它;
对 Null key 和 Null value 的支持: HashMap 可以存储 null 的 key 和 value,但 null 作为键只能有一个,null 作为值可以有多个;Hashtable 不允许有 null 键和 null 值,否则会抛出 NullPointerException。
初始容量大小和每次扩充容量大小的不同 : ① 创建时如果不指定容量初始值,Hashtable 默认的初始大小为 11,之后每次扩充,容量变为原来的 2n+1。HashMap 默认的初始化大小为 16。之后每次扩充,容量变为原来的 2 倍。② 创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小,而 HashMap 会将其扩充为 2 的幂次方大小(HashMap 中的tableSizeFor()方法保证,下面给出了源代码)。也就是说 HashMap 总是使用 2 的幂作为哈希表的大小,上面已经介绍过为什么是 2 的幂次方。
底层数据结构: JDK1.8 以后的 HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)时,将链表转化为红黑树(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树),以减少搜索时间(后文中我会结合源码对这一过程进行分析)。Hashtable 没有这样的机制。
如果想要详细了解这个问题,可以参考我的另一篇文章——Java集合常见面试题(四)
如果想要详细了解这个问题,可以参考我的另一篇文章——Java集合常见面试题(五)
总结:用途(数据库还原 保证事务持久性),(是否为所有引擎共有),(逻辑日志/物理日志),(写入方式)
逻辑日志:可以简单理解为记录的就是sql语句;
物理日志:因为mysql数据最终是保存在数据页中的,物理日志记录的就是数据页变更。
Spring是java企业版(Java Enterprise Edition,JEE,也称J2EE)的轻量型代替品,无需开发重量级的Enterprise JavaBean (EJB),Spring为企业级java开发提供了一种相对简单的方法,通过依赖注入和面向切面编程,用简单的java对象(Plain Old java Object,POJO)实现了EJB的功能。
虽然Spring的组件代码是轻量级的,但它的配置却是重量级的。
一开始,spring用XML配置,而且是很多XML配置。
Sring2.5引入了基于 注解的组件扫描,这消除了大量针对应用程序自身组件的显示XML配置。
Spring3.0引入了基于 java的配置 ,这是一种类型安全的可重构配置方式,可以代替XML。
此外,项目的依赖管理也是一件耗时耗力的事情。
在环境搭建时,需要分析要导入哪些库的坐标,而且还需要分析导入与之有依赖关系的其他库的坐标,一旦选错依赖的版本,随之而来的不兼容问题就会严重阻碍项目的开发进度。
总结:需要手动编写大量配置文件(xml),需要自己进行项目依赖管理。
Spring Boot 可以快速创建独立的Spring应用程序。
Spring Boot 内嵌了如Tomcat,Jetty和Undertow这样的容器,也就是说可以直接运行,不用再做部署工作了。
Spring Boot 无需再像Spring一样使用一堆繁琐的xml文件配置。
Spring Boot 可以自动配置(核心)Spring。SpringBoot将原有的XML配置改为Java配置,将bean注入改为使用注解注入的方式(@Autowire、@Resource),并将多个xml、properties配置浓缩在一个appliaction.yml配置文件中。
Spring Boot 提供了一些现有的功能,如量度工具,表单数据验证以及一些外部配置这样的一些第三方功能。
Spring Boot 可以快速整合常用依赖(开发库,例如spring-webmvc、jackson-json、validation-api和tomcat等),提供的POM可以简化Maven的配置。当我们引入核心依赖时,SpringBoot会自引入其他依赖。
总结一下:可以快速创建独立的Spring应用程序,简化配置无需配置大量xml文件,内嵌了Tomcat、Jetty等Servlet容器可以轻松运行 SpringBoot Web项目,可以快速整合一些常用的依赖。