• java面试题基础


    hashMap原理

    hashMap是数组+链表的数据结构
    每一个数组元素中都是一个链表
    通过记录的关键字key.hashCode()%数组的长度 来决定记录在数组中的存储位置
    对于数组的同一个存储位置,后来的元素永远放在链表的表头

     HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,让后找到bucket位置来  储存值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。HashMap使用链表来解决碰撞问题,当发生碰撞了,对象将会储存在链表的下一个节点中。 Ha  shMap在每个链表节点中储存键值对对象。

     当两个不同的键对象的hashcode相同时会发生什么? 它们会储存在同一个bucket位置的链表中。键对象的equals()方法用来找到键值对。

     因为HashMap的好处非常多,我曾经在电子商务的应用中使用HashMap作为缓存。因为金融领域非常多的运用Java,也出于性能的考虑,我们会经常用到HashMap和ConcurrentHashMap

    饿汉式单例

    public class Singleton {
        private static Singleton instance = new Singleton();
        private Singleton() {}
        public static Singleton getInstance() {
            return instance;
        }

    懒汉式单例

    public class Singleton {
        private static Singleton instance = null;
        private Singleton() {}
        public static synchronized Singleton getInstance() {
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }

    内部类

    public class Singleton {
        private Singleton() {}
        public static Singleton getInstance() {
            
            return SingletonHold.INSTANCE;
        }
        private static class SingletonHold {
            private static final Singleton INSTANCE = new Singleton();
        }
        
    }

    Java中HashMap遍历的四种方式

    第一种:
      Map map = new HashMap();
      Iterator iter = map.entrySet().iterator();
      while (iter.hasNext()) {
      Map.Entry entry = (Map.Entry) iter.next();
      Object key = entry.getKey();
      Object val = entry.getValue();
      }
      效率高,以后一定要使用此种方式!
    
    
    
    第二种:
      Map map = new HashMap();
      Iterator iter = map.keySet().iterator();
      while (iter.hasNext()) {
      Object key = iter.next();
      Object val = map.get(key);
      }
      效率低,以后尽量少使用!

    1. Map的四种遍历方式
    下面只是简单介绍各种遍历示例(以HashMap为例),各自优劣会在本文后面进行分析给出结论。
    (1) for each map.entrySet() Map<String, String> map = new HashMap<String, String>(); for (Entry<String, String> entry : map.entrySet()) { entry.getKey(); entry.getValue(); } (2) 显示调用map.entrySet()的集合迭代器 Iterator<Map.Entry<String,String>>iterator=map.entrySet().iterator(); while(iterator.hasNext()){ Map.Entry<String,String>entry=iterator.next(); entry.getKey(); entry.getValue(); } (3) for each map.keySet(),再调用get获取 Map<String, String> map = new HashMap<String, String>(); for (String key : map.keySet()) { map.get(key); } (4) for each map.entrySet(),用临时变量保存map.entrySet() Set<Entry<String,String>>entrySet=map.entrySet(); for(Entry<String,String>entry:entrySet){ entry.getKey(); entry.getValue(); }
    
     对于keySet其实是遍历了2次,一次是转为iterator,一次就从hashmap中取出key所对于的value。而entryset只是遍历了第一次,他把key和value都放到了entry中,所以就快了。

    jdk1.8新特性

    速度更快 – 红黑树
    代码更少 – Lambda
    强大的Stream API – Stream
    便于并行 – Parallel
    最大化减少空指针异常 – Optional

    spring IOC和AOP的原理?

    IOC:控制反转也叫依赖注入。利用了工厂模式
    将对象交给容器管理,你只需要在spring配置文件中配置对应的bean以及设置相关的属性,让spring容器来生成类的实例对象以及管理对象。在spring容器启动的时候,
    spring会把你在配置文件中配置的bean都初始化好,然后在你需要调用的时候,就把它已经初始化好的那些bean分配给你需要调用这些bean的类(假设这个类名是A),
    分配的方法就是调用A的setter方法来注入,而不需要你在A里面new这些bean了。
    AOP可以说是对OOP的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,
    用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。
    也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。
    日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。
    实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;
    二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码

    MySQL数据库的四种索引类型

    索引类型主要包括:普通索引,唯一索引,主键索引和组合索引。
    (1)普通索引,就是直接创建简单的索引。CREATE INDEX indexName ON mytable(username(length));
    (2)唯一索引,与普通索引类似,不同的是,Mysql的索引列值必须唯一,但允许有空值。如果是组合索引,
    则列值的组合必须唯一。有以下几种创建方式:CTEATE UNIQUE INDEX indexName ON mytable(username(length))修改表结构; ALTER mytable ADD UNIQUE [indexName] ON (username(length))创建表的时候直接指定。 (
    3)主键索引,它是一种特殊的唯一索引,不允许有空值,一般是在建表的时候同时创建主键索引。 CREATE TABLE mytable(ID INT NOT NULL,username VARCHAR(16) NOT NULL,PRIMARY KEY(ID)); 当然也可以用ALTER命令,记住:一个表只能有一个主键。 (4)组合索引, CTEATE TABLE mytable(ID INT NOT NULL,username VARCHAR(16) NOT NULL,city VARCHAR(50) NOT NULL,age INT NOT NULL);

    乐观锁和悲观锁是两种思想

    乐观锁:乐观锁在操作数据时非常乐观,认为别人不会同时修改数据。因此乐观锁不会上锁,只是在执行更新的时候判断一下在此期间别人是否修改了数据:
    如果别人修改了数据则放弃操作,否则执行操作。 悲观锁:悲观锁在操作数据时比较悲观,认为别人会同时修改数据。因此操作数据时直接把数据锁住,直到操作完成后才会释放锁;上锁期间其他人不能修改数据。

    线程池的几种方式

    newFixedThreadPool(int nThreads)
    创建一个固定长度的线程池,每当提交一个任务就创建一个线程,直到达到线程池的最大数量,这时线程规模将不再变化,当线程发生未预期的错误而结束时,线程池会补充一个新的线程
    newCachedThreadPool()
    创建一个可缓存的线程池,如果线程池的规模超过了处理需求,将自动回收空闲线程,而当需求增加时,则可以自动添加新线程,线程池的规模不存在任何限制
    newSingleThreadExecutor()
    这是一个单线程的Executor,它创建单个工作线程来执行任务,如果这个线程异常结束,会创建一个新的来替代它;它的特点是能确保依照任务在队列中的顺序来串行执行
    newScheduledThreadPool(int corePoolSize)
    创建了一个固定长度的线程池,而且以延迟或定时的方式来执行任务,类似于Timer。

    Spring MVC的优点

    它是基于组件技术的.全部的应用对象,无论控制器和视图,还是业务对象之类的都是 java组件.并且和Spring提供的其他基础结构紧密集成. 
    不依赖于Servlet API(目标虽是如此,但是在实现的时候确实是依赖于Servlet的) 
    可以任意使用各种视图技术,而不仅仅局限于JSP 
    支持各种请求资源的映射策略 
    它应是易于扩展的

    springMVC的原理

     客户端发送请求到DispatcherServlet 

     DispatcherServlet查询handlerMapping找到处理请求的Controller 

     Controller调用业务逻辑后,返回ModelAndView 

     DispatcherServlet查询ModelAndView,找到指定视图 

     视图将结果返回到客户端

  • 相关阅读:
    linux 下常用命令
    Mysql 数据库几种引擎的区别比较
    java 中使用ajax调用后台方法注意事项
    C# HtmlDocument和HtmlNode的使用以及节点的模糊查询
    Visio 保存卡死解决办法
    java outterLoop跳出多重循环用法以及详解
    webapi 文件下载输出接口
    获取web.config 内的值
    xml的读取(曾删改)
    from 验证
  • 原文地址:https://www.cnblogs.com/xzjf/p/10919353.html
Copyright © 2020-2023  润新知