Java面试题更新帖(2020年05月20日更新)

目录

一、Spring

二、SpringMVC

三、Mybatis

四、网络相关


一、Spring

1.谈一谈Spring中的IOC容器和DI依赖注入

答:Spring中的IOC容器,即inverse of control控制反转,举个例子,在使用Spring之前,我们在service层使用dao层的对象时,我们都习惯new一个dao层的对象使用,这是一种很强的依赖,不符合Java中低耦合高内聚的原则,为了解耦,我们就引入了工厂模式,原来我们获取对象的方式都是自己new出来,现在由工厂创建对象提供给我们,原来是我们主动的,现在是被动的,这就称之为控制反转,这个工厂其实是一个Map,我们称之为容器。

SpringIOC容器使用过程
//1.使用 ApplicationContext 接口,就是在获取 spring 容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.根据 bean 的 id 获取对象
IAccountService aService = (IAccountService) ac.getBean("accountService");
System.out.println(aService);
IAccountDao aDao = (IAccountDao) ac.getBean("accountDao");
System.out.println(aDao);

BeanFactory和ApplicationContext的区别?

BeanFactory 才是 Spring 容器中的顶层接口。
ApplicationContext 是它的子接口。
创建对象的时间点不一样。
ApplicationContext:只要一读取配置文件,默认情况下就会创建对象。
BeanFactory:什么使用什么时候创建对象。

IOC中的bean标签?

用于配置对象让 spring 来创建的。
默认情况下它调用的是类中的无参构造函数。如果没有无参构造函数则不能创建成功。

id:给对象在容器中提供一个唯一标识。用于获取对象。
class:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。
scope:指定对象的作用范围。
* singleton :默认值,单例的.
* prototype :多例的.
* request  :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中.
* session  :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中.
* global session  :WEB 项目中,应用在 Portlet 环境.如果没有 Portlet 环境那么
globalSession 相当于 session.
init-method:指定类中的初始化方法名称。
destroy-method:指定类中销毁方法名称。

bean的作用范围和生命周期?

单例对象:scope="singleton"
一个应用只有一个对象的实例。它的作用范围就是整个引用。
生命周期:
对象出生:当应用加载,创建容器时,对象就被创建了。
对象活着:只要容器在,对象一直活着。
对象死亡:当应用卸载,销毁容器时,对象就被销毁了。
多例对象:scope="prototype"
每次访问对象时,都会重新创建对象实例。
生命周期:
对象出生:当使用对象时,创建新的对象实例。
对象活着:只要对象在使用中,就一直活着。
对象死亡:当对象长时间不用时,被 java 的垃圾回收器回收了。

Spring中的依赖注入DI

DI,dependency injection。

构造函数注入

<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
    <constructor-arg name="name" value=" 张三 "></constructor-arg>
    <constructor-arg name="age" value="18"></constructor-arg>
    <constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>

Set方法注入,最常用

<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
    <property name="name" value="test"></property>
    <property name="age" value="21"></property>
    <property name="birthday" ref="now"></property>
</bean>
<bean id="now" class="java.util.Date"></bean>

p命名空间注入,实际上还是调用set方法注入

2.Spring中的注解

@Component:相当于<bean id="" class="">;注解内只有一个属性value,用来指定bean的id值;衍生出了三种注解分别用于三层架构的不同层,@Controller,@Service,@Repository。

@Autowired:自动按照类型注入。当使用注解注入属性时,set方法可以省略。它只能注入其他 bean 类型。当有多个类型匹配时,使用要注入的对象变量名称作为 bean 的 id,在 spring 容器查找,找到了也可以注入成功。找不到就报错。

@Qualifier:在自动按照类型注入的基础之上,再按照 Bean 的 id 注入。它在给字段注入时不能独立使用,必须和@Autowire 一起使用;但是给方法参数注入时,可以独立使用。该注解有一个属性value:指定 bean 的 id。

@Resource:直接按照 Bean 的 id 注入。它也只能注入其他 bean 类型。该注解只有一个属性name:指定 bean 的 id。

@Value:注入基本数据类型和 String 类型数据的,该注解有一个属性value:用于指定值。

@Scope:相当于:<bean id="" class="" scope="">,指定 bean 的作用范围。该注解只有一个属性value:指定范围的值。取值:singleton prototype request session globalsession。

@Configuration:用于指定当前类是一个 spring 配置类,当创建容器时会从该类上加载注解。获取容器时需要使用AnnotationApplicationContext(有@Configuration 注解的类.class)。该注解有一个属性value:用于指定配置类的字节码。

@ComponentScan:用于指定 spring 在初始化容器时要扫描的包。作用和在 spring 的 xml 配置文件中的:
<context:component-scan base-package="com.itheima"/>是一样的。写在@Configuration下面一行,@ComponentScan("com.itheima")

@Bean:该注解只能写在方法上,表明使用此方法创建一个对象,并且放入 spring 容器。name:给当前@Bean 注解方法创建的对象指定一个名称(即 bean 的 id)。

3.谈一谈你对Spring中的AOP的理解

AOP:全称是 Aspect Oriented Programming 即:面向切面编程。简单的说它就是把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源码的基础上,对我们的已有方法进行增强。

连接点(JointPoint):指的是项目中的所有方法,我们可以为每一个方法都加上写日志的代码,所以每一个候选者都是连接点

切入点(pointcut):那我们肯定不是每个方法都要加日志,那些需要处理的连接点我们称作切入点

通知(Advice):写日志的代码就叫做通知,意思就是具体增强的那部分代码

切面(Aspect)切入点+通知=切面

<bean id="log" class="com.wanglei.utils.Logger"></bean>
<!--配置AOP-->
<aop:config>
        <!--配置切入点-->
        <aop:pointcut id="accountServicePoint" expression="execution(* com.wanglei.service.impl.*.*(..))"></aop:pointcut>
        <!--配置切面=通知+切入点-->
        <aop:aspect id="logAdvice" ref="log">
            <!--前置通知-->
            <aop:before method="printLog1" pointcut-ref="accountServicePoint"></aop:before>
            <!--后置通知-->
            <aop:after-returning method="printLog2" pointcut-ref="accountServicePoint"></aop:after-returning>
            <!--异常通知-->
            <aop:after-throwing method="printLog3" pointcut-ref="accountServicePoint"></aop:after-throwing>
            <!--最终通知-->
            <aop:after method="printLog4" pointcut-ref="accountServicePoint"></aop:after>

        </aop:aspect>
</aop:config>

二、SpringMVC

1.SpringMVC的处理流程

(1)客户端发送请求至前端控制器DispatcherServlet;
(2) DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handle;
(3)处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;
(4)DispatcherServlet 调用 HandlerAdapter处理器适配器
(5)HandlerAdapter 经过适配调用 具体处理器(Handler,也叫后端控制器);
(6)Handler执行完成返回ModelAndView;
(7)HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;
(8)DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;
(9)ViewResolver解析后返回具体View;
(10)DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
(11)DispatcherServlet响应用户。

 

2.请求参数的绑定

基本数据类型和String,要求请求路径中必须是key=value格式

    <a href="param?info=wanglei">向后台传递wanglei</a>

    @RequestMapping(path = "/param")
    public String paramMethod(String info){
        System.out.println(info);
        return "success";
    }

POJO对象,要求表单中的name属性和user实体类中的属性必须相同才可以通过set方法注入

    <form action="beanparam" method="post">
        用户名:<input name="username" type="text"><br>
        年&nbsp龄:<input name="userage" type="text"><br>
        账户名:<input name="account.accountname" type="text"><br>
        账户密码:<input name="account.accountpass" type="text"><br>
        <input type="submit" name="提交">
    </form>

    @RequestMapping(path = "/beanparam")
    public String parambeanMethod(User user){
        System.out.println(user);
        return "success";
    }

请求路径占位符绑定参数:要求请求路径必须是/delProducts.do/3格式

    //使用占位符,保证占位符和@PathVariable("ids")一样
    @RequestMapping("/delProducts.do/{ids}")
    @ResponseBody
    public String delProducts(@PathVariable("ids") String ids){
        if (ids.contains(",")){
            String[] split = ids.split(",");
            Integer id = Integer.valueOf(split[0]);
            productService.delProducts(id);
            System.out.println("================id"+id);
        }else {

        }

        return "删除ok";
    }

3.请求参数中文乱码

<filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

4.Cookie和Session

Cookie和Session都是属于javaweb中的会话技术,会话:一次会话类似于生活中的一次谈话,会话技术的作用是在一次会话中共享数据,分为客户端会话技术(cookie)和服务器端会话技术(session)。

HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。

区别:Cookie保存在客户端浏览器中,而Session保存在服务器上。Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。
 

5.转发和重定向

转发:是在服务器内部控制权的转移,是由服务器区请求,客户端并不知道是怎样转移的,因此客户端浏览器的地址不会显示出转向的地址。地址栏不会发生变化。
重定向:是服务器告诉了客户端要转向哪个地址,客户端再自己去请求转向的地址,因此会显示转向后的地址,也可以理解浏览器至少进行了两次的访问请求。地址栏会变化。

6.拦截器和过滤器

1.拦截器与过滤器的功能是非常相似的,拦截器对controller进行拦截,过滤器对servlet、jsp等进行过滤

2.过滤器属于sevlet技术规范,拦截器在SpringMVC中才能使用

3.拦截器只能拦截Controller,无法拦截静态资源,但是过滤器可以

三、Mybatis

1.讲一下你对ORM的理解

ORM,objext realtion mapping,对象关系映射,简单来说就是将dao层的domain包下实体类与数据库表中的每一行对应起来,这样我们在操作实体类的时候就和操作数据库表一样。

2.#{}和${}的区别是什么?

#{}是预编译处理,${}是字符串替换。

Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;

Mybatis在处理${}时,就是把${}替换成变量的值。

使用#{}可以有效的防止SQL注入,提高系统安全性。


四、网络相关

应用层:HTTP、FTP
传输层:TCP、UDP
网络层:IP
数据链路层:
物理层:
TCP:1.使用TCP协议前,必须建立TCP连接,形成传输数据通道;2.传输前采用“三次握手”的方式,是可靠的;3.在连接中可以进行大数据量的传输;4.传输完毕,需要释放连接,效率低
UDP:1.将数据、源、目的封装成数据包,不需要建立连接;2.每个数据包不能超过64k;3.可以广播发送,不需要确认;4.发送结束后无需释放资源,效率高。


TCP的三次握手
第一次握手:客户端发送syn=x包到服务端,syn:同步序列编号
第二次握手:服务端接受syn包,生成确认包ack=x+1,并且发送自己的syn=y包,所以服务端发送syn+ack包,此时服务端状态为SYN_RECV
第三次握手:客户端接收到syn+ack,发送确认包ack=y+1。此时连接建立成功,客户端和服务端均为ESTABLISHED状态

TCP的四次挥手
第一次挥手:客户端发送FIN,用来关闭客户端到服务器的数据传送,然后等待服务器的确认。其中终止标志位FIN=1,序列号seq=u
第二次挥手:服务器收到这个FIN,它发送一个ACK,确认ack为收到的序号加一ack+1
第三次挥手:服务端关闭了服务器到客户端的连接之后,发送一个FIN给客户端
第四次挥手:客户端收到FIN后,并发回一个ACK报文确认,并将确认序号seq设置为收到序号加一。
此时服务端如果回复了,说明关闭失败

五、HashMap、LinkedHashMap、红黑树

HashMap map = new HashMap();实例化后,底层会创建一个长度是16的Entry[] table
map.put(k1,v1)
map.put(k1,v1)
map.put(k1,v1)
map.put(k1,v1)
...
扩容:扩容为原来容量的2倍,并将原来的数组复制过来
首先,执行k1所在类的hashCode()方法计算key1的hash值,通过某种算法得到k1在Entry数组中的位置
若该位置为空,则添加成功,即 k1-v1添加成功
若该位置不为空,意味着该位置上有k2,k3,k4...
    比较k1和k2,k3...的hash值,如果hash值不同,则添加成功,以链表的形式挂在上面
    如果hash值相同,继续调用equals方法,返回true,则使用v1替换
    返回false,则添加成功,以链表的形式挂在上面

当链表的长度大于8,JDK8中采取红黑树存储

红黑树:当插入序列为1,2,3,4,5,6,7,8这样的顺序序列时,普通的二叉查找树会变成一条链表
不利于查找,不再是一个树结构,所以提出了新的概念:平衡二叉树
平衡二叉树有2个代表:2-3树和红黑树
2-3树由2-节点和3-节点组成,每个2-节点存储一个值和2个子树,其中左子树小于这个值,右子树大于这个值
每个3-节点存储2个值和3个子树,左子树小于第一个值,中间子树介于第一个值和第二个值之间,右子树大于第二个值

红黑树其实是2-3树的变种,它使用红连接 代替 3-节点

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值