1.hashmap和hashtable的区别
1.HashMap线程不安全,HashTable线程安全。在hashmap的put方法调用addEntry()方法,假如A线程和B线程同时对同一个数组位置调用addEntry,两个线程会同时得到现在的头结点,然后A写入新的头结点之后,B也写入新的头结点,那B的写入操作就会覆盖A的写入操作造成A的写入操作丢失。
2.hashmap的键值可以为空,HashTable不可为空
3.HashMap继承自AbstractMap类。但二者都实现了Map接口。 Hashtable继承自Dictionary类,Dictionary类是一个已经被废弃的类(见其源码中的注释)。父类都被废弃,自然而然也没人用它的子类Hashtable了。
4.扩容方式不同,HashTable在不指定容量的情况下的默认容量为11,而HashMap为16,Hashtable不要求底层数组的容量一定要为2的整数次幂,而HashMap则要求一定为2的整数次幂。 Hashtable扩容时,将容量变为原来的2倍加1,而HashMap扩容时,将容量变为原来的2倍。 Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是 old*2+1。
5.包含的contains方法不同 HashMap是没有contains方法的,而包括containsValue和containsKey方法;hashtable则保留了contains方法,效果同containsValue,还包括containsValue和containsKey方法。
6.解决hash冲突的方式不同 hashmap用到了数组,链表加红黑树
2.讲一下是springboot(ioc和aop)
3.arraylist和linkedlist的区别
请看6
4.多线程中run和start的区别
run只是一个普通的方法,并不会启动线程,start会启动线程,把方法交给jvm调度
5.讲一下对多线程的理解
6.spring的注入方式
自动装配(注解形式)
@Autowired是由org.springframework.beans.factory.annotation.Autowired提供,换句话说就是由Spring提供;
public class UserService {
@Autowired
private UserDao userDao;
}
@Autowired只按照byType 注入;如上代码所示,这样装配回去spring容器中找到类型为UserDao的类,然后将其注入进来。这样会产生一个问题,当一个类型有多个bean值的时候,会造成无法选择具体注入哪一个的情况,这个时候我们需要配合着@Qualifier使用。
@Resource是由javax.annotation.Resource提供,即J2EE提供,需要JDK1.6及以上。
- 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常 2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;
set方法
在要调用spring管理的对象的类里面要
package com.bless.springdemo.action;
public class SpringAction {
//注入对象springDao
private SpringDao springDao;
//一定要写被注入对象的set方法
public void setSpringDao(SpringDao springDao) {
this.springDao = springDao;
}
public void ok(){
springDao.ok();
}
}
<!--配置bean,配置后该类由spring管理-->
<bean name="springAction" class="com.bless.springdemo.action.SpringAction">
<!--(1)依赖注入,配置当前类中相应的属性-->
<property name="springDao" ref="springDao"></property>
</bean>
<bean name="springDao" class="com.bless.springdemo.dao.impl.SpringDaoImpl"></bean>
构造器
public class SpringAction {
//注入对象springDao
private SpringDao springDao;
private User user;
public SpringAction(SpringDao springDao,User user){
this.springDao = springDao;
this.user = user;
System.out.println("构造方法调用springDao和user");
}
public void save(){
user.setName("卡卡");
springDao.save(user);
}
}
<!--配置bean,配置后该类由spring管理-->
<bean name="springAction" class="com.bless.springdemo.action.SpringAction">
<!--(2)创建构造器注入,如果主类有带参的构造方法则需添加此配置-->
<constructor-arg ref="springDao"></constructor-arg>
<constructor-arg ref="user"></constructor-arg>
</bean>
<bean name="springDao" class="com.bless.springdemo.dao.impl.SpringDaoImpl"></bean>
<bean name="user" class="com.bless.springdemo.vo.User"></bean>
静态工厂
public class SpringAction {
//注入对象
private FactoryDao staticFactoryDao;
public void staticFactoryOk(){
staticFactoryDao.saveFactory();
}
//注入对象的set方法
public void setStaticFactoryDao(FactoryDao staticFactoryDao) {
this.staticFactoryDao = staticFactoryDao;
}
}
package com.bless.springdemo.factory;
import com.bless.springdemo.dao.FactoryDao;
import com.bless.springdemo.dao.impl.FactoryDaoImpl;
import com.bless.springdemo.dao.impl.StaticFacotryDaoImpl;
public class DaoFactory {
//静态工厂
public static final FactoryDao getStaticFactoryDaoImpl(){
return new StaticFacotryDaoImpl();
}
}
<!--配置bean,配置后该类由spring管理-->
<bean name="springAction" class="com.bless.springdemo.action.SpringAction" >
<!--(3)使用静态工厂的方法注入对象,对应下面的配置文件(3)-->
<property name="staticFactoryDao" ref="staticFactoryDao"></property>
</property>
</bean>
<!--(3)此处获取对象的方式是从工厂类中获取静态方法-->
<bean name="staticFactoryDao" class="com.bless.springdemo.factory.DaoFactory" factory-method="getStaticFactoryDaoImpl"></bean>
实例工厂
public class DaoFactory {
//实例工厂
public FactoryDao getFactoryDaoImpl(){
return new FactoryDaoImpl();
}
}
public class SpringAction {
//注入对象
private FactoryDao factoryDao;
public void factoryOk(){
factoryDao.saveFactory();
}
public void setFactoryDao(FactoryDao factoryDao) {
this.factoryDao = factoryDao;
}
}
<!--配置bean,配置后该类由spring管理-->
<bean name="springAction" class="com.bless.springdemo.action.SpringAction">
<!--(4)使用实例工厂的方法注入对象,对应下面的配置文件(4)-->
<property name="factoryDao" ref="factoryDao"></property>
</bean>
<!--(4)此处获取对象的方式是从工厂类中获取实例方法-->
<bean name="daoFactory" class="com.bless.springdemo.factory.DaoFactory"></bean>
<bean name="factoryDao" factory-bean="daoFactory" factory-method="getFactoryDaoImpl"></bean>
7.linux下项目的部署
和windows没啥区别,把war包放在tomcat的wedapp下,在bin目录启动start.sh
8.arraylist是不是线程安全的
www.cnblogs.com/lingshang/p… 这篇可以看下,主要讲了
arraylist的扩容机制?
总的来说就是分两步: 1、扩容把原来的数组复制到另一个内存空间更大的数组中 2、添加元素把新元素添加到扩容以后的数组中
private static final int DEFAULT_CAPACITY = 10; if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } 如果在添加的时候远数组是空的,就直接给一个10的长度 int newCapacity = oldCapacity + (oldCapacity >> 1); oldCapacity >> 1 右移运算符 原来长度的一半 再加上原长度也就是每次扩容是原来的1.5倍 elementData = Arrays.copyOf(elementData, newCapacity); 将原数组拷贝到你自己定义的数组里,而且可以选择拷贝的起点和长度以及放入新数组中的位置
arrayrrlist扩容导致性能的下降如何解决?
用有参构造方法直接指定长度 ArrayList objects = new ArrayList<>(1000);
arraylist插入或删除的元素一定比linkedlist慢吗?
不一定,因为在都要遍历node节点
arraylist是不是线程安全的?
不是线程安全的,java.util.ArrayList 中的 add(E e) 方法里有 size++ 的操作,而 size++ 并不是原子操作,所以如果在 size++ 的过程中,其他线程被调度,并且也去操作同一个 ArrayList,那么 size 的值就可能不准确了。可以用vector或者public static List arrayList = Collections.synchronizedList(new ArrayList());来解决,他们都是线程同步的
怎么把两个arraylist相加?
addAll方法
arraylist和linkedList的区别
1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 (LinkedList是双向链表,有next也有previous)
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
时间复杂度比较:
首先一点关键的是,ArrayList的内部实现是基于基础的对象数组的,因此,它使用get方法访问列表中的任意一个元素时(random access),它的速度要比LinkedList快(O1)。LinkedList中的get方法是按照顺序从列表的一端开始检查,直到另外一端(On)。对LinkedList而言,访问列表中的某个指定元素没有更快的方法了
但在某些情况下LinkedList的表现要优于ArrayList,有些算法在LinkedList中实现时效率更高。比方说,利用Collections.reverse方法对列表进行反转时,其性能就要好些。当要对list进行大量的插入和删除操作时,LinkedList也是一个较好的选择。