1、hashmap的实现原理以及hashtable的线程安全是怎么实现的?
hashmap其实也是一个线性的数组实现的,所以可以理解为其存储数据的容器就是一个线性数组。
首先hashmap里面实现一个静态内部类entry,其重要的属性有 key , value, next,从属性key,value我们就能很明显的看出来entry就是hashmap键值对实现的一个基础bean,我们上面说到hashmap的基础就是一个线性数组,这个数组就是entry[],map里面的内容都保存在entry[]里面。
hashtable容器使用synchronized来保证线程安全,但在线程竞争激烈的情况下hashtable的效率非常低下。因为当一个线程访问hashtable的同步方法时,其他线程访问hashtable的同步方法时,可能会进入阻塞或轮询状态。
concurrenthashmap所使用的锁分段技术,首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。
2、hashmap的put(),get()实现原理?
第一个键值对a进来,通过计算其key的hash得到的index=0,记做:entry[0] = a。一会后又进来一个键值对b,通过计算其index也等于0,现在怎么办?hashmap会这样做:b.next = a,entry[0] = b,如果又进来c,index也等于0,那么c.next = b,entry[0] = c;这样我们发现index=0的地方其实存取了a,b,c三个键值对,他们通过next这个属性链接在一起。所以疑问不用担心。也就是说数组中存储的是最后插入的元素。
get()先定位,再遍历。
3、spring bean的生命周期?
在spring中,singleton属性默认是true,只有设定为false,则每次指定别名取得的bean时都会产生一个新的实例。
3.1:bean的建立:容器寻找bean的定义信息并将其实例化。
3.2:属性注入。
3.3:beannameaware
3.4:beanfactoryaware的setbeanfactory()
3.5:beanpostprocessors的processbeforeinitialization()
3.6:initializingbean的afterpropertiesset():
3.7:bean定义文件中定义init-method:
3.8:beanpostprocessors的processaafterinitialization()
disposablebean的destroy(),bean定义文件中定义destroy-method
4、spring如何管理事务?
spring 的事务,可以说是 spring aop 的一种实现。反射和动态代理。
aop面向切面编程,即在不修改源代码的情况下,对原有功能进行扩展,通过代理类来对具体类进行操作。
spring是一个容器,通过spring这个容器来对对象进行管理,根据配置文件来实现spring对对象的管理。
spring的事务声明有两种方式,编程式和声明式。spring主要是通过“声明式事务”的方式对事务进行管理,即在配置文件中进行声明,通过aop将事务切面切入程序,最大的好处是大大减少了代码量。
5、service层是单例还是多例的?是线程安全的吗?如果要做到多实例怎么做?
spring生成对象默认是单例的。通过scope属性可以更改为多例。
<bean id="user" class="modle.user" scope="prototype">
</bean>
5.1、servlet是单例的,严格地说是一个servletmapping对应一个单例实例
5.2、要维护servlet线程安全有很多办法,通常是使用同步块(或方法)来保护共享数据,其次可以volatile、lock一些锁机制,还可以使用threadlocal来打通安全通道,同时为了线程安全还得阻塞对方线程,其性能非常之差。不要在c层定义变量,防止多线程并发。
6、事物的传播性?数据库的隔离级别?
propagation_required 如果存在一个事务,则支持当前事务。如果没有事务则开启
propagation_supports 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行
propagation_mandatory 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
propagation_requires_new 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
propagation_not_supported 总是非事务地执行,并挂起任何存在的事务。
propagation_never 总是非事务地执行,如果存在一个活动事务,则抛出异常
propagation_nested 如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务,
则按transactiondefinition.propagation_required 属性执行
在默认的情况下,我们采用的是
propagation_required
① serializable (串行化):可避免脏读、不可重复读、幻读的发生。
② repeatable read (可重复读):可避免脏读、不可重复读的发生。
③ read committed (读已提交):可避免脏读的发生。
④ read uncommitted (读未提交):最低级别,任何情况都无法保证。
其中一般数据库默认的为read committed级别。
mysql默认的隔离级别为 repeatable read。
在mysql数据库中查看当前事务的隔离级别:
select @@tx_isolation;
在mysql数据库中设置事务的隔离 级别:
set [glogal | session] transaction isolation level 隔离级别名称;
set tx_isolation=’隔离级别名称;’
记住:设置数据库的隔离级别一定要是在开启事务之前!
7、arraylist如何实现线程安全?
那么为了解决这个线程安全问题你可以这么使用collections.synchronizedlist(),如:
list<map<string,object>> data=collections.synchronizedlist(new arraylist<map<string,object>>());
8、如何配置tomcat内存大小?
tomcat默认可以使用的内存为128mb,在较大型的应用项目中,这点内存是不够的,需要调大。有以下几种方法可以选用:
第一种方法:
windows下,在文件/bin/catalina.bat,unix下,在文件/bin/catalina.sh的前面,增加如下设置:
java_opts='-xms【初始化内存大小】 -xmx【可以使用的最大内存】'
需要把这个两个参数值调大。例如:
java_opts='-xms256m -xmx512m'
表示初始化内存为256mb,可以使用的最大内存为512mb。
第二种方法: 环境变量中设 变量名:java_opts 变量值:-xms512m -xmx512m
第三种方法:前两种方法针对的是bin目录下有catalina.bat的情况(比如直接解压的tomcat等),但是有些安装版的tomcat下没有catalina.bat,这个时候可以采用如下方法,当然这个方法也是最通用的方法:打开tomcathome//bin//tomcat5w.exe,点击java选项卡,然后将会发现其中有这么两项:initial memory pool和maximum memory pool.initial memory pool这个就是初始化设置的内存的大小。maximum memory pool这个是最大内存的大小 设置完了就按确定然后再重启tomcat你就会发现tomcat中jvm可用的内存改变了
在catalina.bat的@echo off下面添加(就是第二行)
set java_opts=-server -xms512m -xmx1024m -xx:maxnewsize=512m -xx:maxpermsize=256m
9、servlet默认实现类?
lservlet接口sun公司定义了两个默认实现类,分别为:genericservlet、httpservlet。
如为get请求,则调用httpservlet的doget方法,如为post请求,则调用dopost方法。因此,开发人员在编写servlet时,通常只需要覆写doget或dopost方法,而不要去覆写service方法
以上就是java面试题(找工作必看)的详细内容。
