1.HashMap的底层实现原理
HashMap是数组+链表组成的实现了Map、Cloneable、Serializable接口,继承了AbstractMap类
HashMap是否线程安全?
HashMap是线程不安全的,在并发的环境下可以使用ConcurrentHashMap。
基本方法的使用
HashMap<Integer,String> map=new HashMap<>();
//添加元素
map.put(1, "a");
map.put(2, "b");
map.put(3, "c");
//键不可重复,值被覆盖
map.put(3, "C");
//通过键删除整个键值对
map.remove(3);
//清空
map.clear();
//是否为空
System.out.println(map.isEmpty());//false
//是否包含4
System.out.println(map.containsKey(4));//false
//是否包含“b”值
System.out.println(map.containsValue("b"));//true
//获取集合元素个数
System.out.println(map.size());//3
//通过键获取值
System.out.println(map.get(3));//C
//获取所有值构成的集合
Collection<String> values=map.values();
for(String v:values){
System.out.println("值:"+v);//值:a 值:b 值:c
}
System.out.println(map);
}
两种遍历方式
public static void main(String[] args) {
Map<String,Integer> map=new HashMap<>();
map.put("小林",21);
map.put("小张",35);
map.put("小王",18);
demo1(map);
demo2(map);
}
//通过Set<K> setKey()方法遍历
private static void demo1(Map<String,Integer> map) {
Set<String> keys=map.keySet();
for (String key:keys){
Integer value=map.get(key);
System.out.println("键为:"+key+"值为:"+value);//键为:小林值为:21
//键为:小王值为:18
//键为:小张值为:35
}
}
//通过Set<Map.Entry<K,V>> entrySet()方法遍历
private static void demo2(Map<String, Integer> map) {
Set<Map.Entry<String,Integer>> kvs=map.entrySet();
for (Map.Entry<String,Integer> kv:kvs){
String kstring=kv.getKey();
Integer istring=kv.getValue();
System.out.println(kstring+"-----"+istring);
//小林-----21
//小王-----18
//小张-----35
}
}
2.HashMap和HashTable的区别
1、继承的父类不同
HashMap继承自AbstractMap类。但二者都实现了Map接口。
Hashtable继承自Dictionary类,Dictionary类是一个已经被废弃的类(见其源码中的注释)。 父类都被废弃,自然而然也没人用它的子类Hashtable了。
2、HashMap线程不安全,HashTable线程安全
3.包含的contains方法不同
HashMap是没有contains方法的,而包括containsValue和containsKey方法;hashtable则保 留了contains方法,效果同containsValue,还包括containsValue和containsKey方法。
4.是否允许null值
Hashmap是允许key和value为null值的,用containsValue和containsKey方法判断是否包含对 应键值对;HashTable键值对都不能为空,否则包空指针异常。
5.计算hash值方式不同
6.扩容方式不同(容量不够)
7.解决hash冲突方式不同(地址冲突)
3.Spring中的常用注解和作用
@Controller 处理http请求的控制器
@RestController
Spring4之后新加入的注解,原来返回json需要@ResponseBody和@Controller配合。
即@RestController是@ResponseBody和@Controller的组合注解。
@RestController
public class HelloController {
@RequestMapping(value="/hello",method= RequestMethod.GET)
public String sayHello(){
return "hello";
}
}
@RequestMapping 配置url映射
@RequestMapping此注解即可以作用在控制器的某个方法上,也可以作用在此控制器类上; @RequestMapping中的method参数有很多中选择,一般使用get/post.
当控制器在类级别上添加@RequestMapping注解时,这个注解会应用到控制器的所有处理器 方法上。处理器方法上的@RequestMapping注解会对类级别上的@RequestMapping的声明 进行补充。
@RequestMapping(value="/queryById") 普通请求
@RequestMapping(value="/hello",method= RequestMethod.GET) get请求
@RequestMapping(value="/hello",method= RequestMethod.POST) post请求
常用的基本上就value和method了。其简化注解有
@GetMapping 等同于 @RequestMapping(method = RequestMethod.GET)
@PostMapping 等同于 @RequestMapping(method = RequestMethod.POST)
@PutMapping 等同于 @RequestMapping(method = RequestMethod.PUT)
@DeleteMapping 等同于 @RequestMapping(method = RequestMethod.DELETE)
@PatchMapping 等同于 @RequestMapping(method = RequestMethod.PATCH)
下面是三层的
@Component 最普通的组件,可以被注入到spring容器进行管理
@Repository 作用于持久层
@Service 作用于业务逻辑层@Resource(这个注解属于J2EE的),默认安照名称进行装配,名称可以通过name属性进行指定
@Resource(这个注解属于J2EE的),默认安照名称进行装配,名称可以通过name属性进行指定(例:@Resource(name="userService"))
4.SpringMVC的执行原理
SpringMVC流程:
01、用户发送出请求到前端控制器DispatcherServlet。
02、DispatcherServlet收到请求调用HandlerMapping(处理器映射器)。
03、HandlerMapping找到具体的处理器(可查找xml配置或注解配置),生成处理器对象及处理器拦截器(如果有),再一起返回给DispatcherServlet。
04、DispatcherServlet调用HandlerAdapter(处理器适配器)。
05、HandlerAdapter经过适配调用具体的处理器(Handler/Controller)。
06、Controller执行完成返回ModelAndView对象。
07、HandlerAdapter将Controller执行结果ModelAndView返回给DispatcherServlet。
08、DispatcherServlet将ModelAndView传给ViewReslover(视图解析器)。
09、ViewReslover解析后返回具体View(视图)。
10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
11、DispatcherServlet响应用户。
涉及组件分析:
1、前端控制器DispatcherServlet(不需要程序员开发),由框架提供,在web.xml中配置。
作用:接收请求,响应结果,相当于转发器,中央处理器。
2、处理器映射器HandlerMapping(不需要程序员开发),由框架提供。
作用:根据请求的url查找Handler(处理器/Controller),可以通过XML和注解方式来映射。
3、处理器适配器HandlerAdapter(不需要程序员开发),由框架提供。
作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler。
4、处理器Handler(也称之为Controller,需要工程师开发)
注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler。
作用:接受用户请求信息,调用业务方法处理请求,也称之为后端控制器。
5、视图解析器ViewResolver(不需要程序员开发),由框架提供
作用:进行视图解析,把逻辑视图名解析成真正的物理视图。
SpringMVC框架支持多种View视图技术,包括:jstlView、freemarkerView、pdfView等。
6、视图View(需要工程师开发)
作用:把数据展现给用户的页面
View是一个接口,实现类支持不同的View技术(jsp、freemarker、pdf等)
具体组件的配置相关,请查阅
spring-webmvc-4.3.2.RELEASE.jar 包
下面
/org/springframework/web/servlet/DispatcherServlet.properties 的相关配置
5.LinkedList和ArrayList的区别
LinkedList():链表(节点)。内存空间不连续。线程不安全。便于增删不便于查询。
ArrayList() :数组。内存空间连续。默认初始容量是10,每次增加一半(右移),线程不安全。 便于查询而不便于增删
两种列表的区别:1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结 构。
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
6.反射的原理
1、反bai射的原理,即是jvm通过字节码class文件,生成相应的对du象。
就像正zhi常生成一个对象一样,都是来源于字dao节码class文件,
之所以叫反射,只是因为他不像正常的对象声明,如A a=new A()的方式。
2、反射在框架中的应用太广,只举一个典型的例子,即Spring中Bean的注入。
bean总是先声明class路径,然后依次生成就可以了。
7.Mybatis的执行原理
一、mybatis的工作原理:
MyBatis 是支持普通 SQL查询,存储过程和高bai级映射的优秀持久层框架。MyBatis 消除du了几zhi乎所有的JDBC代码和参数的手工设置以及结果集的检索。
MyBatis使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Ordinary Java Objects,普通的 Java对象)映射成数据库中的记录。
每个MyBatis应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得。用xml文件构建SqlSessionFactory实例是非常简单的事情。
推荐在这个配置中使用类路径资源,但可以使用任何Reader实例,包括用文件路径或file://开头的url创建的实例。MyBatis有一个实用类----Resources,它有很多方法,可以方便地从类路径及其它位置加载资源。
二、使用mybatis的原因:因为mybatis具有许多的优点,具体如下:
1、简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
2、灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
3、解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
4、提供映射标签,支持对象与数据库的orm字段关系映射。
5、提供对象关系映射标签,支持对象关系组建维护。
6、提供xml标签,支持编写动态sql。
扩展资料:
mybatis的功能构架:
1、API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。
2、数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
3、基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。
8.线程的实现方法
①. 继承Thread类创建线程类
定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。因此把run()方法称为执行体。
创建Thread子类的实例,即创建了线程对象。
调用线程对象的start()方法来启动该线程。
②. 通过Runnable接口创建线程类
定义runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。
创建 Runnable实现类的实例,并依此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
调用线程对象的start()方法来启动该线程。
③. 通过Callable和Future创建线程
创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。
创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。
使用FutureTask对象作为Thread对象的target创建并启动新线程。
调用FutureTask对象的get()方法来获得子线程执行结束后的返回值。
9.如何创建线程池和常用线程池的使用
10.当前端发送ajax请求返回200却进入error,如何处理
出错原因:
前台dataType:"json",而后台返回的数据不符合json规范。
解决方案有两种:
1.前台:让ajax数据返回类型为text而不是json;即dataType: "text";
2.后台:修改后台返回值
11.使用数据库,如何用一张表得到另外一张表
1、如果是整个表复制表达如下:
insert into table1 select*from table2
2、如果是有选择性的复制数据表达如下:
insert into table1(column1,column2,column3...) select column1,column2,colunm3... from table2
3、一个数据库中的表中的数据复制到另一个数据库中的一个表,使用方法如下:
insert into 数据库A.dbo.table1(col1,col2,col3...) select col1,col2,col3... from 数据库B.dbo.table2
12.如何解决后台给前端的接口中出现的跨域问题(@CrossOrigin和网关)
13.有没有使用过ElasticSearch
14.说下你对 Spring AOP 和 IOC 的理解?
1.IOC
许多应用都是通过彼此间的相互合作来实现业务逻辑的,如类A要调用类B的方法,以前我们都是在类A中,通过自身new一个类B,然后在调用类B的方法,现在我们把new类B的事情交给spring来做,在我们调用的时候,容器会为我们实例化。
- IOC容器的初始化过程
资源定位,即定义bean的xml-------》载入--------》IOC容器注册,注册beanDefinition
IOC容器的初始化过程,一般不包含bean的依赖注入的实现,在spring IOC设计中,bean的注册和依赖注入是两个过程,,依赖注入一般发生在应用第一次索取bean的时候,但是也可以在xm中配置,在容器初始化的时候,这个bean就完成了初始化。
-
三种注入方式,构造器、接口、set注入,我们常用的是set注入
-
bean是如何创建--- 工厂模式
-
数据是如何注入-------反射
6.AOP
面向切面编程,在我们的应用中,经常需要做一些事情,但是这些事情与核心业务无关,比如,要记录所有update*方法的执行时间时间,操作人等等信息,记录到日志,
通过spring的AOP技术,就可以在不修改update*的代码的情况下完成该需求。
7.AOP的实现原理------代理
15使用 Spring 或者 SpringBoot 有遇到过什么印象深刻的问题吗?当时是怎么解决的?
16.在项目中如何使用上传,使用什么方式进行上传(阿里的oos)