zoukankan      html  css  js  c++  java
  • Java开发面经(一)

    Nignx用来干嘛的,转发策略?

    静态HTTP服务器,代理静态资源(主流静态资源服务器),转发动态请求,负载均衡等,相对于tomcat等动态资源解析服务器效率更高

    转发策略

    1.默认轮询

    upstream backserver{
    	server 192.168.1.1:8080
    	server 192.168.1.2:8080
    }
    
    

    2.按比重Weight(学的时候时候讲加权随机记成随机了)

    upstream backserver {
    	server 192.168.1.1:8080 weight=3;
    	server 192.168.1.2:8080 weight=7;
    }
    

    3.IP_hash 每个请求按访问ip的hash结果分配,可以解决session登入信息问题

    upstream backserver {
        ip_hash;
        server 192.168.0.14:88;
        server 192.168.0.15:80;
    }
    

    (其他还有第三方的)

    4.fair按响应时间

    upstream backserver {
        server server1;
        server server2;
        fair;
    }
    

    5.url_hash 按访问url的hash结果来分配请求,每个url定向到同一台服务器

    upstream backserver {
        server squid1:3128;
        server squid2:3128;
        hash $request_uri;
        hash_method crc32;
    }
    

    使用

    • upstream:每个设备的状态:
    • down:表示当前的 server 暂时不参与负载
    • weight:默认为 1 weight 越大,负载的权重就越大。
    • max_fails:允许请求失败的次数默认为 1 当超过最大次数时,返回 proxy_next_upstream 模块定义的错误
    • fail_timeout:max_fails 次失败后,暂停的时间。
    • backup:其它所有的非 backup 机器 down 或者忙的时候,请求 backup 机器。所以这台机器压力会最轻
    proxy_pass http://backserver/; 
    upstream backserver{ 
        ip_hash; 
        server 127.0.0.1:9090 down; 
    #(down 表示单前的server暂时不参与负载) 
        server 127.0.0.1:8080 weight=2; 
    #(weight 默认为1.weight越大,负载的权重就越大) 
        server 127.0.0.1:6060; 
        server 127.0.0.1:7070 backup; 
    #(其它所有的非backup机器down或者忙的时候,请求backup机器) 
    } 
    
    
    worker_processes  4;
    events {
    # 最大并发数
    worker_connections  1024;
    }
    http{
        # 待选服务器列表
        upstream myproject{
            # ip_hash指令,将同一用户引入同一服务器。
            ip_hash;
            server 125.219.42.4 fail_timeout=60s;
            # fail_timeout:max_fails次失败后,暂停的时间
            server 172.31.2.183;
        }
    
        server{
            # 监听端口
            listen 80;
            # 根目录下
            location / {
            # 选择哪个服务器列表
                proxy_pass http://myproject;
            }
    		
        }
    }
    

    ActiveMQ使用场景?

    消息队列引入主要是为了,异步,解耦,削峰。可以理解成两个应用程序间(生产者消费者间)的通信。

    请求发给队列后立即返回,费者进程从消息队列中获取数据,异步写入数据库,延迟可得到有效改善

    需要使用消息机制的地方,比如:发布,订阅,发送点对点消息;

    需要使用队列的地方,比如:秒杀,抢票,订单处理,短信发送模块。(前后端速度不一致)

    Spring MVC 工作流程,常用注解

    常用注解

    @Controller:标识这个类是一个控制器

    @RequestMapping:给控制器方法绑定一个uri

    @ResponseBody:将java对象转成json,并且发送给客户端

    @RequestBody:将客户端请求过来的json转成java对象

    @RequestParam:当表单参数和方法形参名字不一致时,做一个名字映射

    @PathVarible:用于获取uri中的参数,比如user/1中1的值

    Rest风格的新api

    @RestController相当于@Controller+ @ResponseBody

    @GetMapping@DeleteMapping@PostMapping@PutMapping

    其他注解

    @SessionAttribute:声明将什么模型数据存入session

    @CookieValue:获取cookie值

    @ModelAttribute:将方法返回值存入model中

    @HeaderValue:获取请求头中的值

    工作原理

    请求DispatcherServlet—>映射处理器返回控制器—>处理适配器执行控制器返回ModelAndView—>解析视图—>渲染视图—>返回响应

    具体:

    1、用户发送请求至前端控制器DispatcherServlet。

    2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。

    3、处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

    4、 DispatcherServlet调用HandlerAdapter处理器适配器。

    5、HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。

    6、Controller执行完成返回ModelAndView。

    7、HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。

    8、DispatcherServlet将ModelAndView传给ViewReslover视图解析器。

    9、ViewReslover解析后返回具体View.

    10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。

    11、DispatcherServlet响应用户。

    img

    关于Spring 中IOC和AOP的理解,以及常用到注解

    IOC

    控制反转,将对象的创建权交由Spring容器来完成,然后注入对象(DI依赖注入)

    实现注入主要是通过bean后置处理器BeanPostProcessor接口的实现类

    • 基于构造函数的依赖注入

    • 基于设置函数的依赖注入

    • 基于自动装配的依赖注入

      自动装配有三种模式:byType(类型模式),byName(名称模式)、constructor(构造函数模式)

    • 基于注解的依赖注入

      @Autowired byType,多个实例配合@Qulifier指定名字,如果要允许null值,可以设置它的required属性为false

      @Resource 默认ByName,可指定

    AOP

    面向切面编程,纵向重复,横向抽取

    应用:日志,权限,调试,事务

    Aspect,Join Point,Advice(Before,After,After-returning,After-throwing,Around,Pointcut)Introduction,Target Object,AOP Proxy,Wearving

    本质是Java的动态代理和CGLIB字节码增强

    JDK动态代理
    利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生成一个实现代理接口的匿名类,

    在调用具体方法前调用InvokeHandler来处理。

    CGLiB动态代理
    利用ASM开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

    实现CGLIB动态代理必须实现MethodInterceptor(方法拦截器)接口

    区别

    jdk只能针对接口不能针对类实现代理。

    CGLib通过继承方式实现代理。所以类或方法最好不要声明成final,对于final类或方法,是无法继承的。

    选择

    1)当Bean实现接口时,Spring就会用JDK的动态代理。

    2)当Bean没有实现接口时,Spring使用CGlib是实现。

    3)可以强制使用CGlib(在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>)。

    @Aspect
    @Component//配置bean
    public class WebLogAspect {
        private Logger logger = Logger.getLogger(getClass());
    
        @Pointcut("execution(public * com.jibny.boot.projects.web.controller..*.*(..))")
        public void webLog() {}
    
        @Before("webLog()")
        public void doBefore(JoinPoint joinPoint) throws Throwable {
            // 接收到请求,记录请求内容
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            // 记录下请求内容
            logger.info("---------------request----------------");
            logger.info("URL : " + request.getRequestURL().toString());
            logger.info("HTTP_METHOD : " + request.getMethod());
            logger.info("IP : " + request.getRemoteAddr());
            Enumeration<String> enu = request.getParameterNames();
            while (enu.hasMoreElements()) {
                String name = (String) enu.nextElement();
                logger.info("name:" + name + " - value:" + request.getParameter(name));
            }
        }
        @AfterReturning(returning = "ret", pointcut = "webLog()")
        public void doAfterReturning(Object ret) throws Throwable {
            logger.info("---------------response----------------");
            // 处理完请求,返回内容
            logger.info("RESPONSE : " + ret);
        }
    }
    

    聊一聊Mybatis

    1.读取配置文件,包含数据库连接信息和Mapper映射文件或者Mapper包路径,

    2.通过SqlSessionFactoryBuilder创建SqlSessionFactory,

    3.SqlSessionFactory建立SqlSession(方法结束后关闭),目的执行sql语句

    4.解析sql动态标签为对应sql,并将其封装进MapperStatement对象,通过executor执行返回结果

    注解绑定Sql:@Select@Update@Delete@Insert

    XML绑定Sql

    ​ 需要注意的地方namespace指定类的全类名

    ​ parameterType查询参数

    ​ resultType属性应该和表字段对应

    ​ if-test实现动态Sql

    <mapper namespace="top.shmly.mapper.UserMapper">    
        <select id="findUserByIds" parameterType="list" resultType="user">
            <!-- SELECT * FROM user WHERE id in (1,2,3) -->
            SELECT * FROM user
            <where>
                <if test="list != null and list.size > 0">
                    <foreach collection="list" item="id" 						open="id in(" close=")" separator=",">
                        ${id}
                    </foreach>
                </if>
            </where>
        </select>
    </mapper>
    

    resultMap属性名和对应数据库表中的字段名不同时可以指定字段,可以实现延迟加载(不需要立即返回关联查询结果,查询订单,不一定需要及时返回订单对应的产品信息),实现比较麻烦,用于多表模型中嵌套模型(多表也可以封装成VO用resultType)

    assocication可以指定联合的对象

    <resultMap id="userResultMap" type="user">
        <id property="id" column="id_"></id>
        <result property="username" column="username_"></result>
        <result property="sex" column="sex_"></result>
        <result property="birthday" column="birthday_"></result>
        <result property="address" column="address_"></result>
    </resultMap>
    <select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap">
        SELECT
         id id_,
         username username_,
         sex sex_,
         birthday birthday_,
         address address_
        FROM user WHERE id = #{id}
    </select>
    
    
    

    mapper逆向工程以及继承tk.mapper

    逆向生成通过mybatis-generator对数据库表自动生成单表查询的model,modelExample,mapper接口,mapper.xml,通过Example.Criteria进行条件筛选。

    缺点:数据库表字段变动,配置文件就要修改,批量操作要重写,不支持分页,可移植性差

    通用mapper,引入依赖继承Mapper接口,通用 Mapper 中已经写好了一些常用的内置接口,全局Example类,属性加了 (持久化)注解,支持批量和分页等操作

    @Id标记主键,@Column(name = "真实名称"),@Tranisent忽略字段

    Spring Boot自动装配

    @SpringBootApplication组合注解

    • @SpringBootConfiguration
    • @EnableAutoConfiguration
    • @ComponentScan

    通过其中@EnableAutoConfiguration开启自动装配

    @EnableAutoConfiguration开启自动装配-->@Import({EnableAutoConfigurationImportSelector})导入配置-->SpringFactoriesLoader.loadFactoryNames扫描META-INF/spring.factories文件-->AutoConfiguration依赖包下的类@Conditional条件注解

    @ConditionalOnBean
    @ConditionalOnClass
    @ConditionalOnMissingBean
    ......
    
    
    
    mysql索引

    索引可以优化查询和检索速度,避免全表扫描,创建索引条件一般为where子句后字段

    mysql索引采用B+树数据结构,类似平衡二叉树变种,非叶子节点存指针指向子节点的地址,只有叶子节点存数据,从左到右有序非递减。

    索引是在存储引擎层实现的,而不是在服务器层实现的,所以不同存储引擎具有不同的索引类型和实现。InnoDB 的 B+Tree 索引分为主索引和辅助索引。

    主索引的叶子节点 data 域记录着完整的数据记录,这种索引方式被称为聚簇索引。因为无法把数据行存放在两个不同的地方,所以一个表只能有一个聚簇索引。

    辅助索引的叶子节点的 data 域记录着主键的值,因此在使用辅助索引进行查找时,需要先查找到主键值,然后再到主索引中进行查找。

    索引的使用原则和注意事项
    • 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。
    • 除了数据表占数据空间之外,每一个索引还要占一定的物理空间。如果要建立聚簇索引,那么需要的空间就会更大。
    • 当对表中的数据进行增加、删除和修改的时候,索引也要动态地维护,这样就降低了数据的维护速度。

    建索引遵循原则:

    • 在经常需要搜索的列上建立索引,可以加快搜索的速度。
    • 在作为主键的列上创建索引,强制该列的唯一性,并组织表中数据的排列结构。
    • 在经常使用表连接的列上创建索引,这些列主要是一些外键,可以加快表连接的速度。
    • 在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,所以其指定的范围是连续的。
    • 在经常需要排序的列上创建索引,因为索引已经排序,所以查询时可以利用索引的排序,加快排序查询。
    • 在经常使用 WHERE 子句的列上创建索引,加快条件的判断速度。

    总体回答的一般漏了挺多,准备了很多(Java基础集合,多线程,事务和锁)都没讲

  • 相关阅读:
    python学习之路-day3
    python学习之路-day2
    python学习之路-day1
    Hystrix断路器
    jmater的使用
    记录1
    springcloud-Gateway
    Quartz框架
    红黑树的左旋和右旋
    异步回调CompletableFuture
  • 原文地址:https://www.cnblogs.com/binjz/p/12501381.html
Copyright © 2011-2022 走看看