-
一、创建线程的方法
1.继承Thead类创建线程
2.实现Runnable接口创建线程
3.使用Callable和Future创建线程
4.优势和区别
(1)实现Runnable/Callable接口相比继承Thread类的优势
①适合多个线程进行资源共享 。
②可以避免java中单继承的限制。
③增加程序的健壮性,代码和数据独立。
④线程池只能放入Runnable或Callable接口实现类,不能直接放入继承Thread的类。
(2)Callable和Runnable的区别
①Callable重写的是call()方法,Runnable重写的方法是run()方法。
②call()方法执行后可以有返回值,run()方法没有返回值。
③call()方法可以抛出异常,run()方法不可以。
④运行Callable任务可以拿到一个Future对象,表示异步计算的结果 。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。
=========================================================
二、创建线程池
1.Executors类 直接创建
2.ThreadPoolExecutor类
(1)ThreadPoolExecutor类一共有四个构造方法,传入参数一致(不同的参数启用不同的线程池)
①参数配置详解:
1)corePoolSize:线程池中的线程数量;
2)maximumPoolSize:线程池中的最大线程数量;
3)keepAliveTime:当线程池线程数量超过corePoolSize时,多余的空闲线程会在多长时间内被销毁;
4)unit:keepAliveTime的时间单位;
5)workQueue:任务队列,被提交但是尚未被执行的任务;
a.SynchronousQueue-直接提交队列
b.LinkedBlockingQueue-无界的任务队列
6)ThreadFactory:线程工厂,用于创建线程,一般情况下使用默认的,即Executors类的静态方法defaultThreadFactory();
7)handler:拒绝策略。当任务太多来不及处理时,如何拒绝任务。
a.DiscardOldestPolicy策略:丢弃任务队列中最早添加的任务,并尝试提交当前任务;
b.CallerRunsPolicy策略:调用主线程执行被拒绝的任务,这提供了一种简单的反馈控制机制,将降低新任务的提交速度。
c.DiscardPolicy策略:默默丢弃无法处理的任务,不予任何处理。
d.AbortPolicy策略:直接抛出异常,阻止系统正常工作。
②参数之间的关系
1)corePoolSize <= maximumPoolSize。
2)若当前线程池中线程数 < corePoolSize,则每来一个任务就创建一个线程去执行;
3)若当前线程池中线程数 >= corePoolSize,会尝试将任务添加到任务队列。如果添加成功,则任务会等待空闲线程将其取出并执行;
4)若队列已满,且当前线程池中线程数 < maximumPoolSize,创建新的线程;
5)若当前线程池中线程数 >= maximumPoolSize,则会采用拒绝策略(JDK提供了四种,下面会介绍到)。
6)SynchronousQueue:直接提交队列。SynchronousQueue没有容量,所以实际上提交的任务不会被添加到任务队列,总是将新任务提交给线程执行,如果没有空闲的线程,则尝试创建新的线程,如果线程数量已经达到最大值(maximumPoolSize),则执行拒绝策略。
7)LinkedBlockingQueue:无界的任务队列。当有新的任务来到时,若系统的线程数小于corePoolSize,线程池会创建新的线程执行任务;当系统的线程数量等于corePoolSize后,因为是无界的任务队列,总是能成功将任务添加到任务队列中,所以线程数量不断增加。若任务创建的速度远大于任务处理的速度,无界队列会快速增长,直到内存耗尽。
=========================================================
三、线程池有几种
1.FixedTheadPool:线程数量固定的的线程池
(1)把任务交给线程,线程会按照设置的固定线程数量范围,来反复地执行我们的任务, 不会超出我们设置的固定数量范围。列如:设置为5,始终是0~4的5个线程反复执 行。
2.CachedThreadPool:可缓存的线程池,并且会回收
(1)把任务交给线程,如果线程不够用的话,就会创建线程。如果线程过多,就会自动把 线程给回收。
3.ScheduleThreadPool:支持定期和周期执行任务的线程池
(1)支持设置每隔多长时间去执行任务。这个线程池用在我们的定时任务或者是用来替代 定时器。
4.SingleThreadExecutor:只有一个线程的线程池
(1)用唯一的工作线程来执行任务,与FixedTheadPool原理一致,设置线程固定数量 范围为1。
=========================================================
四、Struts2自带过滤器
StrutsPrepareAndExecuteFilter
(1)如果是2.1.3之前的版本,用org.apache.struts2.dispatcher.FilterDispatcher,否则,用org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter。
(2)初始化参数
①config参数:指定要加载的配置文件。逗号分割。
②actionPackages参数:指定Action类所在的包空间。逗号分割。
③configProviders参数:自定义配置文件提供者,需要实现ConfigurationProvider接口类。逗号分割。
=========================================================
五、IO 和NIO的区别
1.NIO就是New IO在JDK1.4中引入,IO和NIO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO更快。
2.IO面向流,NIO面向缓冲区
3.IO是阻塞的,如果读写数据调用时数据还没有准备好,或者目前不可写,那么读写操作就会被阻塞直到数据准备好或目标可写为止,当面对多个流的读写时需要多个线程处理,read/write是阻塞的。NIO是非阻塞的,数据读写调用都会立即返回,并将目前可读(或可写)的内容写入缓冲区或者从缓冲区中输出,即使当前没有可用数据,调用仍然会立即返回并且不对缓冲区做任何操作,NIO提供
Selector
实现单个线程管理多个channel的功能,选择通道时,可能是阻塞的,也可能是非阻塞的,但是read/write是非阻塞的。(IO
要求一次完成任务,NIO允许多次完成任务)六、Mybatis怎么实现防止sql注入
1.Mybatis提供了两种传参格式(#{}、${})。
①使用#{}相当于底层JDBC使用PreparedStatement类,PreparedStatement类会对SQL进行预编译,SQL执行时,直接使用编译好的SQL,替换SQL中的占位符“?”即可。
②使用${}相当于是输出变量的值,未经过预编译,SQL执行时,会直接将传输的值拼接在传参的位置,无法防止SQL注入。
=========================================================
七、线程安全和线程不安全
1.线程安全:指的是多个线程在执行同一段代码的时候采用加锁机制,使每次的执行结果和单线程执行的结果都是一样的,不存在执行线程时出现意外结果。某个函数、函数库在并发环境中被调用时,能够正确的处理多个线程之间的共享变量,使程序功能正确完成。
2.线程不安全: 是指不提供加锁机制保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据。
=========================================================
八、Mybatis的9种动态标签
1.if : 当参数满足条件才会执行某个条件
2.choose、when、otherwise : choose标签是按顺序判断其内部when标签中的test条件是否成立,如果有一个成立,则choose结束;如果所有的when条件都不满足时,则执行otherwise中的SQL。
3.where标签: 会在只有一个或以上的if条件满足的情况下才去插入WHERE关键字,如果WHERE后的内容是”AND”或”OR”开头的,where也会根据语法去除”AND”或”OR”。
4.set标签: 会动态前置SET关键字,同时也会消除无关的逗号(结尾逗号)。
5.trim标签: 可实现where/set标签的功能
①prefix:表示在trim标签包裹的SQL前添加指定内容
②suffix:表示在trim标签包裹的SQL末尾添加指定内容
③prefixOverrides:表示去掉(覆盖)trim标签包裹的SQL指定首部内容,去掉多个内容写法为and |or(中间空格不能省略)(一般用于if判断时去掉多余的AND |OR)
④suffixOverrides:表示去掉(覆盖)trim标签包裹的SQL指定尾部内容(一般用于update语句if判断时去掉多余的逗号)
6.foreach: 对集合进行遍历
①collection:迭代集合的名称,可以使用@Param注解指定,该参数为必选(java入参,相对于#{listName})。
②item:表示本次迭代获取的元素,若collection为List、Set或数组,则表示其中元素;若collection为Map,则代表key-value的value,该参数为必选。
③index:在List、Set和数组中,index表示当前迭代的位置,在Map中,index指元素的key,该参数是可选项。
④open:表示该语句以什么开始,最常使用的是左括弧”(”,MyBatis会将该字符拼接到foreach标签包裹的SQL语句之前,并且只拼接一次,该参数是可选项。
⑤close:表示该语句以什么结束,最常使用的是右括弧”)”,MyBatis会将该字符拼
⑥separator:MyBatis会在每次迭代后给SQL语句添加上separator属性指定的字符,该参数是可选项。
7.bind:可以从OGNL(对象图导航语言)表达式中创建一个变量并将其绑定到上下文,name属性重新命名参数,value属性对值做字符串拼接。
=========================================================
九、@Autowired和@Resource的区别
1.@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。
2.@Autowired是spring提供的注解,默认按类型装配。@Resource是java提供的,默认按照名称装配,通过名称匹配不到bean时,才按照类型装配,如果设置了name属性,就只会按照名称装配。
=========================================================
十、mysql和oracle分页查询的区别
1.Mysql用limit分页
(1)select * from tableName LIMIT n,m
①n 表示起始行
②m表示取多少行
2.Oracle用rownum分页
(1)SELECT * FROM ( SELECT ROWNUM RN,* FROM TABLENAME WHERE ROWNUM<=X // X = startPager * pageSize ) A WHERE A.RN >= Y
①Y 表示起始行
②X 表示结束行
③注意: ROWNUM只能比较小于不能比较大于,所以 >=Y 要用别名比较
=========================================================
十一、Rabbitmq设计模式
1.Rabbitmq使用的是发布订阅模式:
(1)发布订阅模式中,发布者与订阅者毫无关联,完全解耦,他们通过经纪人Broker来进行交流,发布者只需通知Broker要发布的topic(###),而Broker会主动推送给订阅了topic
(###)消息的订阅者,或者由订阅者主动向Broker订阅topic(###)的消息。
2.拓展:观察者模式:
(1)观察者模式中的角色有:观察者、被观察者,两者面向接口,松耦合,业务数据是被观察对象,用户界面是观察者,被观察者发生改变的时候,观察者就会观察到这样的变化,并且做出相应的响应。
关于工作一年第一次面试遇到的问题
于 2022-04-27 10:14:12 首次发布