面试题相关

面试高频面试题

1.hashMap和hashTable的区别    

 hashMap支持null键和null值,hashTable不支持null键和null值.
    hashMap对null值做了特殊处理,当出现null值的时候会将hashCode设为0.
    hashMap初始值为16,每次扩容为之前的2倍,hashTable初始值为11,每次扩容为原来的2n+1.
    hashMap不是同步的,是线程不安全的,执行效率高;hashTable是同步的,是线程安全的,执行效率低.
    hashTable已经被淘汰.


2.多线程 

    创建线程的三种方式
        (1).继承Thread类,实现run方法
        (2).实现runable接口.
        (3).使用Callable,Futureh创建一个线程
        使用callable和Future创建的线程调用是有返回值
    多线程的5中状态
     新建
     就绪
     运行
     阻塞
     死亡
    
    线程优先级设置
         Thread的setPriority()方法  默认优先级是5
    线程睡眠
         Thread的sleep(时间) 使线程转到阻塞状态
    线程等待
         Object的wait()  线程等待  知道其他线程调用此对象的notify()或notifyAll()唤醒方法
    线程唤醒
         Object的notify()方法唤醒单个线程
     线程让步
         Thread.yield()
     线程加入
         Thread.join()

     wait()和sleep()的区别
         wait是Object的方法,sleep是Thread类的方法
         共同点
             他们都是在多线程环境下,都可以在调用处指定阻塞指定的毫秒值.
         不同点:
             1.sleep()睡眠时,保持对象锁,仍然占有该锁,wait()睡眠时,释放对象锁
             2.wait,notify,notityAll只能在同步控制方法和同步控制块中使用,而sleep可以在任何地方


    常用的线程池
        java自带线程池ThreadPoolExecutor
        spring自带的线程池:ThreadPoolTaskExecutor

3.事务

    事务的特性:ACID 原子性 一致性 隔离性 持久性
        原子性:事务不可分割,要么全部完成,要么全部不完成.如果在事务过程中出现错误,则全部回滚.
        一致性:事务结束前和结束后,数据库的完整性约束没有被破环.比如A向B转账,不能A扣了钱,B没有却没有收到.
        隔离性:同一时间,只允许一个事务请求同一数据,不同事务之间彼此没有任何干扰,比如A正在从一张银行卡中取钱,在A取钱结束之前,B不能向这张卡转账
        持久性:事务完成之后,事务对数据库的所有更新将被保存到数据库,不能回滚.

    事务的隔离级别:读未提交  读已提交  可重复读  串行化
        读未提交什么都不能防止
        读已经提交可以有效防止脏读  orcal ,sql server
        可重复读可防止可重复读,脏读  mysql默认的事务隔离级别
        串行化可防止脏读,不可重复读,幻读

    事务并发引发的问题:
        脏读:一个事务读取了一个事务未提交的数据
        不可重复读:一个事务读取表中的某一行数据,多次读取结果不同
            脏读和不可重复读的区别是:脏读是读取了前一事务还未提交的数据,不可重复读是重新读取了前一事务提交的数据
        幻读:一个事务读取到了别的事务插入的数据,导致前后查询不一致

        不可重复读和幻读的区别是:不可重复读侧重的修改,幻读侧重的是新增和删除.解决不可重复读的方法是锁住满足条件的行,解决幻读的方案是锁表

    说明:1.串行化效率很低,读写数据都会锁住整张表
         2.隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大,鱼和熊掌不可兼得啊。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为读已提交,它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、幻读这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。


    涉及到相关高并发的问题
        乐观锁和悲观锁
            乐观锁:
            悲观锁:两种实现方式:版本号和时间戳
            
如何处理并发和同步
    java代码层面:
        java中的同步锁,synchronized
    数据库层面:
        使用乐观锁悲观锁
4.redis

    常见的nosql数据库
        redis mongDB Couchbase(CouchDB的合并版本)
    redis的数据类型
        String(字符串)
        Hash(哈希)
        List(列表)
        Set(集合)
        zSet(有序集合)
    redis的持久化方案
        RDB持久化
            在指定时间内将内存中的数据集快照写入到磁盘
            优点:只有一份rdb文件,可随时备份
                 比AOF文件小,加载效率高.
                 不阻塞主进程,io效率高
        AOF持久化
            将每一个操作以日志的形式记录在服务器,在redis启动之初读取文件来重新构建数据库,保证启动后数据库中的数据是完整的
            优点:每次改动同步数据安全性好
                 以append的方式追加日志,不会对旧日志文件产生影响


5.spring的生命周期

6.索引的类型

    创建索引的方式
    索引的分类
        主键缩影 唯一索引 普通索引 全文索引  组合索引  
    索引的结构
        b+tree索引 hash索引
        b+tree是使用最频繁的索引数据结构,b+tree的速度比不上hash,但b+tree很适合做排序操作

    普通索引:最基本的索引,没有任何限制
    唯一索引:与"普通索引"类似,不同的就是:索引列的值必须唯一,但允许有空值。
    主键索引:它 是一种特殊的唯一索引,不允许有空值。
    全文索引:仅可用于 MyISAM 表,针对较大的数据,生成全文索引很耗时好空间。
    组合索引:为了更多的提高mysql效率可建立组合索引,遵循”最左前缀“原则。创建复合索引时应该将最常用(频率)作限制条件的列放在最左边,依次递减。

7.dubbo和http的相比

8.页面加载慢如何处理

    前端处理
        优化图片
        使用nginx做负载,做请求分发
        利用浏览器缓存
        压缩css和javascript
    后台处理
        将不经常变动的页面使用模版引擎进行页面静态化的操作
        优化sql


9.数据库设计

    三大范式:
        1.1NF强调列的原子性,即每一列不能够再分成其他几列
        2.2NF每一个实例或者行都可以被唯一的区分(每一列都可以被主键区分,每一列都和主键又关系)
        3.3NF在第二范式上更进一层,确保每一列和主键都是直接相关而不是间接相关
    反范式:
        通过增加冗余字段或添加重复的数据来提高数据库的读性能
    每张表必须有主键

10.数据库优化

    当只查询一条数据时使用LIMIT 1
    选择正确的存储引擎(MyISAM和InnoDB  MyISAM不适用大量读写操作    InnoDB支持行锁和事务)
    使用Not Exists 代替 NOT IN (NOT Exists使用了索引,NOT In不走索引)
    数据库分库分表  垂直拆分:按照功能模块,关系密切程度拆分成多表
                    水平拆分,按照规则分成多个相关表
    对应数据量大经常查询的数据进行列添加索引


11.框架部分

    spring
         spring的生命周期
             在配置bean元素中,init-method指定bean的初始化方法,destroy-method指定销毁方法
         spring实例化的几种方式
             使用类构造器实例化(默认无参的)
             静态工厂实例化(简单工厂模式)
             动态工厂实例化(工厂方法模式)
         AOP
         IOC
         DI
         spring的注入方式
             接口注入
             构造方法注入
             set方法注入
             spring4支持@AutoWirde自动注入
         BeanFactory接口和 ApplicationContext 接口有什么区别 ?
            1.ApplicationContext接口继承BeanFactory接口,Spring核心工厂是BeanFactory ,BeanFactory采取延迟加载,第一次getBean时才会初始化Bean,ApplicationContext是会在加载配置文件时初始化Bean。

            2.ApplicationContext是对BeanFactory扩展,它可以进行国际化处理、事件传递和bean自动装配以及各种不同应用层的Context实现

            3.开发中基本都在使用ApplicationContext,web项目使用WebApplicationContext ,很少用到BeanFactory

        spring bean的作用域
            singleton :在整个应用中是单例的
            prototype :一个bean可以定义多个实例
            request: 每次的http请求都会创建一个bean
            Session: 在一个HTTP Session中,一个bean对应一个实例
            global-session:在一个HTTP Session中,一个bean定义一个实例

     mybatis
         mybatis循环
         CDATA
         mybatis返回id
         #{}和${}取值的区别
             #{}是占位符可以防止sql注入

         resultType的区别resultMap

     springmvc的执行流程
         用户发起请求-->
         前端控制器接收到请求-->
         处理器映射器找到相对应的controller类-->
         在到处理器适配器执行controller所对应的方法-->
         返回到视图解析器-->
         渲染视图响应结果

         1、用户发送请求至前端控制器DispatcherServlet
        2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。
        3、处理器映射器找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给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响应用户

12.分布式事务解决方案

    两阶段提交
    补偿事务
    本地消息表
    MQ事务消息,目前只有RocketMQ支持

13.关于集合

    Iterator
        ListIterator
    Collection
        List
            ArrayList
            LinkedList
        Set
            HashSet
                LinkHashSet
            TreeSet
    Map
         HashMap
             LinkHashMap
         TreeMap

    集合和数组的区别
        数组的长度是固定的,集合的长度是可变的
        数据可以存放基本数据类型也可以存放引用数据类型,集合只能存储引用数据类型
        数组只能存储的元素必须是同意数据类型,集合存储的对象可以是不同的数据类型

    集合类的结构组成
        colltction
            List:有序(元素存入集合和取出的顺序一致,元素有索引,元素可以重复)
            Set:无序(元素存入集合和取出的顺序不一致,不可以存储重复的元素.必须保证元素唯一性)


        List接口  有序 有索引 可重复
            ArrayList:底层数据是数组,线程不同步.查询速度快
            LinkList:底层数据是链表结构,线程不同步,增删元素都非常快
            Vector:底层结构是数组,线程同步,无论是查询还是增删都比较慢

        Set
            HashSet:底层是hash表 线程不同步 无序 高效
                LinkHashSet:    有序  hashSet的子类
            TreeSet:对Set集合中的元素进行指定的顺序排序.不同步.TreeSet底层是二叉树

            TreeSet集合排序有两种方式,Comparable和Comparator区别:
            1:让元素自身具备比较性,需要元素对象实现Comparable接口,覆盖compareTo方法。
            2:让集合自身具备比较性,需要定义一个实现了Comparator接口的比较器,并覆盖compare方法,并将该类对象作为实际参数传递给TreeSet集合的构造函数。
            第二种方式较为灵活。

        Map
            HashMap:底层是hash表结构,线程是不同步的,可以存储null键null值.
            HashTable:底层是hash表接口,线程是同步的.不可以存储null键null值.
            TreeMap:底层是二叉树结构,可以对map中指定的键进行排序.


        HashMap和HasnTable底层的实现原理
            HashMap和Hashtable的底层实现都是数组+链表结构实现的,这点上完全一致

            增,删,查都是先计算hash,然后根据hash和table.length来计算idnex也就是table的索引.然后进行响应的操作

            HashMap()创建
                HashMap创建会创建一个默认容量为16的Entry数组,默认加载因子为0.75,同时设置值临界值为16*0.75
            put()方法
                hashMap会对null值进行特殊处理,总是放到table[0]的位置
                put过程是先计算hash然后通过hash与table.length取摸计算index值,然后将key放到table[index]位置,当table[index]已存在其它元素时,会在table[index]位置形成一个链表,将新添加的元素放在table[index],原来的元素通过Entry的next进行链接,这样以链表形式解决hash冲突问题,当元素数量达到临界值(capactiy*factor)时,则进行扩容,是table数组长度变为table.length*2

            get()方法
                同样当key为null时会进行特殊处理,在table[0]的链表上查找key为null的元素
                get的过程是先计算hash然后通过hash与table.length取摸计算index值,然后遍历table[index]上的链表,直到找到key,然后返回

            remove方法
                remove方法和put get类似,计算hash,计算index,然后遍历查找,将找到的元素从table[index]链表移除    
            resize方法
                resize方法在hashmap中并没有公开,这个方法实现了非常重要的hashmap扩容,具体过程为:先创建一个容量为table.length*2的新table,修改临界值,然后把table里面元素计算hash值并使用hash与table.length*2重新计算index放入到新的table里面这里需要注意下是用每个元素的hash全部重新计算index,而不是简单的把原table对应index位置元素简单的移动到新table对应位置
            clear()方法
                clear方法非常简单,就是遍历table然后把每个位置置为null,同时修改元素个数为0
                需要注意的是clear方法只会清楚里面的元素,并不会重置capactiy
            containsKey和containsValue
                containsKey方法是先计算hash然后使用hash和table.length取摸得到index值,遍历table[index]元素查找是否包含key相同的值

                containsValue方法就比较粗暴了,就是直接遍历所有元素直到找到value,由此可见HashMap的containsValue方法本质上和普通数组和list的contains方法没什么区别,你别指望它会像containsKey那么高效

            hash和indexFor
                indexFor中的h & (length-1)就相当于h%length,用于计算index也就是在table数组中的下标
                hash方法是对hashcode进行二次散列,以获得更好的散列值
                为了更好理解这里我们可以把这两个方法简化为 int index= key.hashCode()/table.length,以put中的方法为例可以这样替换


设计模式:

    单例模式:
    工厂模式:


dubbo:
dubbo的序列化方式

posted @ 2018-12-17 09:37  HaniLucky  阅读(120)  评论(0编辑  收藏  举报