zoukankan      html  css  js  c++  java
  • Java基础

    Java基础

    标签(空格分隔): 面试


    1. 重载和重写

    • 重载: 表示同一个类中可以有多个名称相同的方法, 但是需要参数列表不同(即参数个数和参数类型不同).
    • 重写: 表示将子类中的方法与父类中的某个方法的名称和参数完全相同,这个时候子类重写了父类的该方法, 这个是多态性的一种表现.

    子类覆盖父类的时候只能抛出比父类更少的异常, 因为子类用于解决父类存在的一些问题, 所以不能比父类有更多的问题. --- 越来越完美

    子类方法的访问权限只能比父类的更大,不能更小, 如果父类的该方法使用私有修饰符修饰的话, 这样就不存在继承. --- 越来越开放.


    2. 抽象类和接口的区别

    参数 抽象类 接口
    默认的方法实现 可以有默认的方法实现 接口是抽象的,不存在方法的实现(JDK8 default).
    实现 子类使用extend关键字来继承抽象类,如果子类不是抽象类的话,他需要提供抽象类中所有声明方法的实现. 子类使用关键字来implates来实现接口, 他需要提供接口中所有声明的方法和实现.
    构造器 抽象类可以有构造器 接口不能有构造器
    与正常的Java类的区别 除了不能实例化抽象类之外,它和普通的Java类没有区别(实例化抽象类, 其实是匿名类,需要将其中所有的抽象函数实现之后可以实现匿名类.) 接口和类不是同一个东西.
    访问修饰符 抽象方法可以有public,protected,default这些访问修饰符. 接口方法默认的修饰符是public,你不可以使用其他修饰符
    main方法 抽象方法可以有main方法,并且我们可以运行它 接口没有main方法,因此我们不能运行它
    多继承 抽象方法可以继承一个类和实现多个接口 接口只能继承一个或者多个其他接口
    速度 比接口的速度更快 接口式比较慢的,因为它需要时间去寻找在类中实现的方法
    添加新方法 如果向抽象类中添加新的方法,你可以给他提供默认的实现,因此你不需要改变你现在的代码 如果在接口中添加方法,那么你必须改变实现该接口的类.
    package pers.ycy.base;
    
    public class FinalClass {
        public static void main(String[] args) {
            Animal ag = new Dog();
            new Dog();
            new Dog().run();
            Animal animal = new Animal() {
                @Override
                protected void sing() {
                    System.out.println("sing");
                }
            };
            animal.sing();
        }
    }
    
    /**
     * 抽象类, 动物.
     */
    abstract class Animal {
        int age;
        String name;
    
        public static void main(String[] args) {
            Animal sing_sing = new Animal() {
                @Override
                protected void sing() {
                    System.out.println("sing sing");
                }
            };
            sing_sing.run();
        }
    
        // 每次创建 新对象的时候会调用一次, 运行优先级 高于构造函数 低于静态代码块.
        {
            System.out.println("构造代码块");
        }
    
        // 在第一次创建对象的时候会执行一次. 运行优先于 构造代码块,  通常用于初始化只调用一次的数据, 例如: 初始化程序的运行配置信息
        static {
            System.out.println("静态代码块");
        }
    
        Animal() {
            System.out.println("抽象类的构造函数");
        }
    
        abstract protected void sing();
    
        protected void run() {
            {
                int x = 10;
                System.out.println(x);
                System.out.println("用于限定变量的作用域.");
            }
            System.out.println("动物是可以跑得");
        }
    }
    
    class Dog extends Animal {
    
        @Override
        protected void sing() {
            System.out.println("汪汪");
        }
    }
    abstract class AGou extends Dog{
    
    }
    
    public class FinalClass {
        public static void main(String[] args) {
            Dog dog = new Dog();
            dog.eat();
        }
    }
    
    /**
     * 接口和类 是不同的, 抽象类中的 构造代码块, 静态代码块, 构造函数. 接口中是没有的.
     */
    interface Animal{
        default void eat(){
            System.out.println("接口的默认方法, 如果使用该方法, 则该方法需要对所有实现该接口的类都有用 .");
        }
    }
    class Dog implements Animal{
        
    }
    

    3. 说说反射的用途和实现

    反射的用途
    • Java的反射机制是一个非常强大的功能, 在很多的项目当中都可以看到反射的身影Spring, Mybatis.通过反射机制我们可以在运行期间获取对象的类型信息. 利用这一点我们可以实现工厂模式和代理模式等设计模式, 同时也可以解决Java的泛型擦除问题.
    反射的实现
    • 获取一个对象对应的反射类在,Java方法中有下面几种方法可以获得反射类.
    1. getClass()
    2. Class.forName()
    3. 类.class
    4. 通过类加载器实现, getClassLoader()

    4. Session和Cookie的区别

    1. Cookie是存放在客户端上的,Session存放在服务器上.
    2. Cookie不是很安全, 别人可以分析存放在本地的Cookie并进行Cookie欺骗,考虑到安全应当使用Session.
    3. Session会在一定时间内保存在服务器上, 当访问增多的时候会比较占用服务器的性能, 考虑到减轻服务器的压力应当使用Cookie.
    4. 单个Cookie保存的数据不应当超过4k, 很多浏览器限定一个站点最多保存20个Cookie.

    5. GET请求和POST方式的区别

    1. 根据Http规范,GET用于信息获取, 而且应该是安全的和幂等性[1]
    2. 根据HTTP规范,POST请求可以改变服务器上的资源.
    3. 首先是"GET方式提交的数据最多只能是1024字节",因为GET是通过URL提交数据,那么GET可提交的数据量就和URK长度有直接的关系了.而实际上,URL参数不存在上限,HTTP协议规范没有对URL长度进行限制,这个限制是特定的浏览器以及服务器对它的限制,IE对URL长度的限制是2083(2k+35).对于其他浏览器. 一般没有长度限制
    4. POST没有大小限制,HTTP协议规范也没有进行大小限制.

    6. Session分布式处理


    6.1 Session复制

    在支持Session复制的Web服务器上,通过修改Web服务器的配置,可以实现将Session同步到其它Web服务器上,达到每个Web服务器上都保存一致的Session.

    1. 优点: 代码上不需要做支持和修改.
    2. 缺点: 需要依赖支持Session复制的Web服务器, 一旦更换成不支持的Web服务器就不能使用了, 并且在用户量巨大的情况下可能会造成Session大爆炸.
    3. 适用场景: 只适用于Web服务器比较少并且Session数据量比较小的情况.
    4. 可用方案: 开源方案 tomcat-redis-session-manager, 暂不支持Tomcat8.

    6.2 Session 粘滞

    将用户的每次请求都通过某种方法强制分发到某一个Web服务器上,只要这个Web服务器上存储了相应的Session数据,就可以实现会话跟踪.

    1. 优点: 使用简单,没有额外开销.
    2. 缺点: 一旦某个Web服务器重启或者宕机,相对应的Session数据也会丢失,而且需要依赖负载均衡机制.
    3. 适用场景: 对稳定性要求不是很高的业务情景.

    6.3 Session集中管理

    在单独的服务器或者服务器集群上使用缓存技术,如Redis存储Session数据,集中管理所有的Session.所有的Web服务器都从这个存储介质中去的对应的Session,实现Session共享.

    1. 优点: 可靠性高,减少Web服务器的资源开销.
    2. 缺点: 实现上有些复杂,配置较多.
    3. 适用场景: Web服务器较多,要求高可用性的情况.
    4. 可用方案: 开源方案Spring Session,也可以自己实现,主要是重写HttpServletRequestWrapper中的getSession方法.

    6.4 基于Cookie管理

    这种方式每次发起请求的时候都需要将Session数据放到Cookie中传递给服务端.

    1. 优点: 不需要依赖额外外部存储,不需要额外配置.
    2. 缺点: 不安全,已被带去或篡改;Cookie的长度和数量有限制,需要消耗更多的网络带宽.
    3. 使用场景:数据不重要,不敏感且数据量较小的情况.

    7. JDBC的流程

    • DriverManager类注册驱动数据库驱动程序.
    • 调用DriverManager.getConnection方法,通过JDBC URL将用户名,密码,数据表等信息传入,以得到数据库链接.
    • 获取Connection之后,便可以通过createStatement创建Statement用以执行SQL语句.
    • 有时候会得到查询结果,比如select,得到查询结果,查询的结果存放于(ResultSet)当中.
    • 关闭数据库语句,关闭数据库链接.

    8. MVC设计思想

    MVC是三个单词的首字母缩写, 他们是Model, View, Controller. 这个模式认为, 程序不论简单与复杂, 从结构上来看,都可以分为三层:

    1. 最顶层(View): 直接面向用户的视图层. 它是提供给用户的操作界面, 是程序的外壳.
    2. 最底层(Model): 核心的用户层, 也就是程序需要操作的数据或信息.
    3. 中层(Controller): 根据用户从"视图层"输入的指令,选取"数据层"中的数据,然后对其进行相应的操作,产生最终的结果.

    9. equals==的区别

    两个对象用equals比较返回true,那么两个对象的hashcode方法必须返回相同的结果.

    • 问题: 如若相反的话, hashtable中, 两个自认为相同的对象(equalstrue), 在取值和存值的时候就会出现, 下表地址不同的情况. 这样就麻烦很大了.

    两个对象用equals比较返回false,那么两个对象的hashcode方法也不一定返回不同的值,但是最好返回不同的值,这样可以提高哈希表的性能.

    • 两个自认为不同的对象, 在hashtable中存取值的时候下标居然相同. 这样问题就很大.

    根据第二点,重写equals的时候,必须重写hashcode,以确保equals方法相等的时候两个对象的hashcode返回相同的值.

    • 由上述的两点 , equalshashcode应该保持一致性.
    • set集合去重的时候, 判断是否相等用的是 哈希值和equals同时成立与否. 这样也可以看出应该让 equalshashcode应该保持一致性.
    1. equals==的区别是: ==用于比较原生类型,而equals方法用于检查对象的相等性.
    2. 如果==equals用于比较对象,当两个引用地址相同,==返回true.而equals可以返回truefalse主要取决于重写的实现.最常见的一个例子,字符串的比较,不同情况==equals返回不同的结果.

    10. listmap的区别.

    Map是键值对的方式进行存储的, 根据值去获取键, List是根据下标进行存储的, 所以必须要有顺序,有下标才能顺利的进行存取. 但是Map就不需要下标,且没有顺序. 只需计算Hash值即可

    Map接口有三个实现类: HashMap,HashTable,LinkedHashMap.

    List接口有三个实现类: LinkList,ArrayList,Vector.

    LinkedList: 底层基于链表实现, 链表内存是散乱的, 每一个内节点都存储着 上一个节点的地址和下一个节点的地址以及本身的值.

    Map相当于和Collection一个级别的, Map集合存储键值对,且要求保持键的唯一性.

    Map是基于哈希存储的所以要求保持键的唯一性.

    其中区别: List特点 元素放入有顺序,元素且可以重复. Map特点 元素按键值对存储,无放入顺序.


    11. ListSet的区别

    ListSet都是继承自Collection接口.
    List特点: 要么是链表要么是顺序数组,所以有顺序,元素可重复.
    Set特点: HashSet(底层是HashMap),LinkedHashSet.


    12. ArrayListLinkList的区别

    其实就是顺序数组和链表的区别


    13. ArrayListVector的区别

    都是顺序数组, 但是Vector是线程安全的,ArrayList是线程不安全的.
    Vector的数据增长是原来的一倍, ArrayList是增加原来的50%.

    • 堆栈,队列,这种经常存储和删除的应该使用Vector这样可以减少因为扩容产生的时间消耗.
    • 快速读取等操作应该使用ArrayList.

    14. HashMapHashTable

    HashMap几乎可以等价于HashTable,除了HashMap是非synchronized的,并且可以接受null(HashMap可以接受为null的键值和值,而HashTable则不可以).

    HashMap是非synchronize,而HashTablesynchronize的.这意味着HashTable是线程安全的,多个线程可以共享一个HashTable,如果没有一个正确的同步的话,多个线程是不能共享HashMap的, Java5提供了ConcurrentHashMap,它是HashMap的替代,比HashMap的扩展性更好.


    15. 线程安全问题

    • 最简单的方式,Synchronization关键字.
    • 使用java.util.concurrent.atomic包中的原子类, 例如AtomicInteger.
    • 使用 java.util.concurrent.locks 包中的锁
    • 使用线程安全的集合 ConcurrentHashMap
    • 使用 volatile 关键字,保证变量可见性(直接从内存读,而不是从线程 cache 读)

    在JVM底层volatile 是采用“内存屏障”来实现的.
    缓存一致性协议(MESI协议)它确保每个缓存中使用的共享变量的副本是一致的。其核心思想如下:当某个 CPU 在写数据时,如果发现操作的变量是共享变量,则会通知其他 CPU 告知该变量的缓存行是无效的,因此其他 CPU 在读取该变量时,发现其无效会重新从主存中加载数据


    16. synchronizedlock 的区别

    • synchronizedlock 的区别

    • synchronized(隐式锁): 在需要同步的对象中加入此控制, synchronized方法上, 也可以加在特定代码块中, 括号中表示需要上锁的对象.

    • lock(显示锁): 需要显示指定其实位置和终止位置. 一般使用ReentrantLock类作为锁, 多个线程中必须要使用一个 ReentrantLock 类做为对象才能保证锁的生效。且在加锁和解锁处需要通过 lock()unlock() 显示指出。所以一般会在 finally 块中写 unlock() 以防死锁。

    • synchronizedlock 性能区别

    • synchronized 是托管给 JVM 执行的,而 lockJava 写的控制锁的代码。在 JDK 1.5 中,synchronize 是性能低效的。因为这是一个重量级操作,需要调用操作接口,导致有可能加锁消耗的系统时间比加锁以外的操作还多。相比之下使用 Java 提供的 Lock 对象,性能更高一些。但是到了 JDK 1.6,发生了变化。synchronize 在语义上很清晰,可以进行很多优化,有适应自旋,锁消除,锁粗化,轻量级锁,偏向锁等等。导致在 JDK 1.6synchronize 的性能并不比 Lock 差。

    17. Java跳出 一重以上循环的方式。

    public static void main(String[] args) {     
        ok:                                      
        for(int i=0;i<10;i++){                   
            for(int j=0;j<10;j++){               
                if(j==5){                        
                    System.out.println("j==5");  
                    break ok;                    
                }                                
            }                                    
        }                                        
    }                                            
    

    18. final

    final 修饰一个关键字的时候,是栈内存不能变,和堆内存无关。

    public static void main(String[] args) {
        final StringBuilder a = new   StringBuilder("1qwe");
            a.append("asdasd");
    }
    


    1. 一次请求和多个请求对于同一个资源来说应该具有同样的结果(网络超时,电脑爆炸之类的不算数.). ↩︎

  • 相关阅读:
    mysql myisam转innodb的2种方法
    利用apache限制IP并发数和下载流量控制
    详细说明phpmyadmin连接,管理多个mysql服务器
    [LeetCode] Add Digits
    [LeetCode] Move Zeroe
    [LeetCode] Construct String from Binary Tree
    [LeetCode] Find the Difference
    [LeetCode] Invert Binary Tree
    [LeetCode] Find All Numbers Disappeared in an Array
    [LeetCode] Detect Capital
  • 原文地址:https://www.cnblogs.com/A-FM/p/12673825.html
Copyright © 2011-2022 走看看