【方向盘】JavaSE/EE基础面试题、基础知识记录---大杂烩(中)

简介: 【方向盘】JavaSE/EE基础面试题、基础知识记录---大杂烩(中)

for循环声明上调用方法,下面例子,方法被调用了几次呢?


public static void main(String[] args) {
        System.out.println("================普通for循环:");
        for (int i = 0; i < getData().size(); i++) {
            System.out.println(i);
        }
        System.out.println("================增强for循环:");
        for (Integer i : getData()) {
            System.out.println(i);
        }
        System.out.println("================Java8提供的foreach循环:");
        getData().forEach(System.out::println);
    }
    private static List<Integer> getData() {
        System.out.println("getDate被调用...");
        var list = new ArrayList<Integer>();
        list.add(10);
        list.add(20);
        list.add(30);
        return list;
    }


原因剖析,可参见另外一篇博文:【小家java】剖析for、while、foreach、标签循环语句的控制( break,continue,return )


怎么判断A是否是B的子类、实例等等


    public static void main(String[] args) {
        //若我们得到的都只有Class类对象  可以这么判断
        Class<Number> numberClass = Number.class;
        Class<Long> longClass = Long.class;
        boolean assignableFrom = numberClass.isAssignableFrom(longClass); //longClass是否归属于numberClass
        System.out.println(assignableFrom); //true  说明long是number的子类
        //进而可以各种强转
        Class<? extends Number> aClass = longClass.asSubclass(numberClass);
        System.out.println(aClass); //class java.lang.Long  若没报错 说明转换完成
        //如果你是两个实例
        Long lon = new Long(100);
        boolean b = lon instanceof Number;
        System.out.println(b); //true
        //转换
        Number cast = Number.class.cast(lon);
        //lon.getClass().cast(Number.class); //这是错误写法
        System.out.println(cast); //100
    }

说说Java中常用的几种数据结构?


数据元素相互之间的关系称为结构。有四类基本结构:集合、线性结构、树形结构、图状结构;Java中有几种常用的数据结构,主要分为Collection和Map两个主要接口,而程序中最终使用的数据结构是继承自这些接口的数据结构类

数组、链表、红黑树、哈希表等

什么叫hash碰撞?hashMap是怎么解决碰撞问题的?


如果两个输入串的hash函数的值一样,则称这两个串是一个碰撞(Collision)。既然是把任意长度的字符串变成固定长度的字符串,所以必有一个输出串对应无穷多个输入串,碰撞是必然存在的。

通常有两类方法处理碰撞:开放寻址(Open Addressing)法和链接(Chaining)法。前者是将所有结点均存放在散列表T[0…m-1]中;后者通常是把散列到同一槽中的所有元素放在一个链表中,而将此链表的头指针放在散列表T[0…m-1]中。显然HashMap采用链表法


说说get请求和Post请求的基本区别:


      1.get参数通过url传递,post放在request body中。


      2.get请求在url中传递的参数是有长度限制的,而post没有。(HTTP协议规范没有对URL长度进行限制,但各大浏览器和web服务器加了限制。要支持IE,则最大长度为2083byte,若只支持Chrome,则最大长度 8182byte)


      3.get比post更不安全,因为参数直接暴露在url中,所以不能用来传递敏感信息。


      4.get请求只能进行url编码,而post支持多种编码方式


      5.get请求会浏览器主动cache,而post则需要设置参数


      6.get请求参数会被完整保留在浏览历史记录里,而post中的参数不会被保留。


      7.GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。


      8.GET产生一个TCP数据包;POST产生两个TCP数据包。

对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);

而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)


(据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。)


mysql分布式集群实现原理?


mysql-cluster配置管理节点、数据节点

集群主要分成三大类( 高可用集群, 负载均衡集群,科学计算集群)


   1.高可用集群:活动节点一般只有一个,如Nginx。常见的就是2个节点做成的HA集群,有很多通俗的不科学的名称,比如"双机热备", “双机互备”, “双机”.


   2.负载均衡集群(Load Balance Cluster):集群中所有的节点都处于活动状态,它们分摊系统的工作负载。一般Web服务器集群、数据库集群和应用服务器集群都属于这种类型。


   3.高性能计算(High Perfermance Computing)集群,简称HPC集群。这类集群致力于提供单个计算机所不能提供的强大的计算能力。


说说分布式和集群的区别:


集群是个物理形态,分布式是个工作方式。

1、只要是一堆机器,就可以叫集群,他们是不是一起协作着干活,这个谁也不知道;一个程序或系统,只要运行在不同的机器上,就可以叫分布式

2、集群可能运行着一个或多个分布式系统,也可能根本没有运行分布式系统;分布式系统可能运行在一个集群上,也可能运行在不属于一个集群的多台(2台也算多台)机器上。

3、分布式是相对中心化而来,强调的是任务在多个物理隔离的节点上进行。中心化带来的主要问题是可靠性,若中心节点宕机则整个系统不可用,分布式除了解决部分中心化问题,也倾向于分散负载,但分布式会带来很多的其他问题,最主要的就是一致性。

4、分布式:一个业务分拆多个子业务,部署在不同的服务器上(集群是解决高可用的)

5、集群:同一个业务,部署在多个服务器上(分布式是解决高性能、高并发的)


zookeeper有什么用?


分析zookeeper到底能做什么?


分布式接口的幂等性设计?


分布式系统接口幂等性设计


分布式系统的接口幂等性设计


深度优先与广度优先的区别?


广度优先和深度优先的区别


jstack,jmap,jutil分别的意义?


jstack,jmap,jutil分别的意义


有界、无界队列对ThreadPoolExcutor执行的影响?

有界、无界队列对ThreadPoolExcutor执行的影响


通过面试题来看,可以看出目前互联网公司面试考点为:

1.性能调优、算法数据机构

2.高并发下数据安全、接口冪等性、原子性等

3.分布式下协同、已经锁的处理

4.数据库的分库分表、项目之间的垂直拆分

出现频率高的技术点有:

1.HashMap

2.JVM

3.Dubbo

4.Mybatis

5.Zookeeper

6.http tcp/ip

简述Spring是怎么巧妙的解决bean循环依赖问题的?


Spring-bean的循环依赖以及解决方式


Spring循环依赖的三种方式


判断下面多线程环境下,输出顺序?


    public static void main(String[] args) throws ExecutionException, InterruptedException {
                ExecutorService executorService = Executors.newFixedThreadPool(1);
        Future<Integer> submit = executorService.submit(() -> {
            System.out.println("子线程开始执行...");
            return 10;
        });
        //TimeUnit.SECONDS.sleep(1);
        System.out.println(submit);
    }
输出:
java.util.concurrent.FutureTask@76fb509a
子线程开始执行...
原因:系统创建一个子线程是需要时间开销的,所以肯定主线程先打印了
-----------------------------------------------------
取消掉注释语句,输出:
开始执行...
java.util.concurrent.FutureTask@76fb509a
原因:创建子线程虽有时间开销,但不可能有1s之久
-----------------------------------------------------
注释加上,但把最后一句输出改为:System.out.println(submit.get()); 输出:
开始执行...
10
原因:get()方法是阻塞的,因此肯定得子线程完全结束后,才会继续主线程


使用多种方法,计算1至10000000的正整数之和?


1、forloop

2、多线程

3、线程池

4、ForkJoin

5、并行流


LockSupport有了解过吗?park()和unpark()方法呢?


说说Thread.join()方法的使用方式?怎么实现t1、t2并行,但它俩执行都完成后才让主线程执行呢?


说说eq和==的区别?==依赖于HashCode重写吗?HashMap和IdentityHashMap的区别在哪儿呢?


Java中基本数据类型占用字节数?位数呢?Long和double在64位的虚拟机上的线程安全问题有研究过吗?


byte 1字节

short 2字节

int 4字节

long 8字节

char 2字节(C语言中是1字节)可以存储一个汉字

float 4字节

double 8字节

boolean false/true(理论上占用1bit,1/8字节,实际处理按1byte处理)


JAVA是采用Unicode编码。每一个字节占8位。你电脑系统应该是 32位系统,这样每个int就是 4个字节 其中一个字节由8个二进制位组成


Map的put方法返回值是什么?什么时候会返回null呢?


返回null的情况有两种,请分别说出


书写一小段代码,怎么快速证明Long类型是64位的?


怎么证明int是32位的? Long的十进制最多多少位呢?(正数19位,负数20位,因为符号也是个字符)

说说intValue、valueOf、parseInt三方法的区别:

贴源码,一切尽在不言中


// intValue  返回的是基本数据类型
    public int intValue() {
        return value;
    }
    public long longValue() {
        return (long)value;
    }
    public double doubleValue() {
        return (double)value;
    }
//valueOf 返回的包装类型 我们发现valueOf方法是有缓存的,因此效率高。如果需要转化的是字符串,会先调用parseInt方法
public static Integer valueOf(String s) throws NumberFormatException {
        return Integer.valueOf(parseInt(s, 10));
    }
public static Integer valueOf(String s, int radix) throws NumberFormatException {
        return Integer.valueOf(parseInt(s,radix));
    }
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
//parseInt 返回的int类型
    public static int parseInt(String s) throws NumberFormatException {
        return parseInt(s,10);
    }
public static int parseInt(String s, int radix)
                throws NumberFormatException
    {"较为复杂的代码"}


valueof调用了parseInt方法的,底层有依赖

因此如果只是想把字符串变为数字这么简单,那parseInt效率比valueof效率高

Integer a=new Integer(1);

Integer a=Integer.valueOf(1);

两个都是得到一个Integer对象,但是Integer.valueOf的效率高,开销更小。


如何优雅的设计一个流水号生生成器?位运算熟吗?


要求流水号有规律,但是又不能完全有规律,且应该包含一些有用信息,且要求效率高

问题:有一串数字5937594375973495743,怎么样可以快速的萃取出最后面指定位数的数字?请书写一个函数实现。(提示:使用按位与 & 的语法)


说说你对String 常量池的理解?举几个相等的例子?什么时候被放进去?intern()方法有什么用?常量池在JVM内存什么位置呢?常量池有哪三种?


String a = "计算机" + "软件"; 这句话常量池里会放几个

答案:由于JVM存在编译期优化,对于两个直接双引号声明的String的+操作,JVM在编译期会直接优化为“计算机软件”一个字符串。同String a = “计算机软件”,效果是一样的。

参考例子:java7,8中的String pool


字面量是会直接放在String pool中的,其他的你可以通过intern自己放入


一个list,怎么把它转换为数组?

List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
//方式一:只能转换为Object[]数组  请注意使用
String[] array= (String[]) list.toArray(); //java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
//方式二
Integer[] ints = list.toArray(new Integer[0]); //这里面写0还是写几效果是一样的
//方式三  这种写法也是ok的
       Integer[] ints = new Integer[][list.size()];
        list.toArray(ints);
        System.out.println(ints);
//方式四:这种错误很隐蔽 请类型方便千万不要搞错了
        Long[] longs = list.toArray(new Long[0]);
        System.out.println(longs); //Exception in thread "main" java.lang.ArrayStoreException
//方式五:如果你用Object接受,就肯定不会有问题了。同toArray()方法
        Object[] objects = list.toArray(new Object[0]);
        System.out.println(objects); 
//方式六:其余自己循环遍历的方式 此处省略



说说你对java中守护线程的理解,怎么创建一个守护线程?可以有多个吗?


1、User和Daemon两者几乎没有区别,唯一的不同之处就在于虚拟机的离开(但凡只要还有一个User线程在运行,守护线程就不会退出)


2、daemonThread.setDaemon(true); (必须在start()方法调用之前执行这句话,否则会跑出一个IllegalThreadStateException异常)


3、在Daemon线程中产生新的线程也是守护线程


如你可以线程池中自定义ThreadFactory,然后t.setDaemon(true);那么线程池中所有的线程都是守护线程了。也就不用显示调用pool.shutdown();才能关闭线程池了,自己就会结束了


4、不要认为所有的应用都可以分配给Daemon来进行服务,比如读写操作或者计算逻辑(因为这样的话,主线程在推出之前,无法知道守护线程是否已经完成读写任务)


守护线程–也称“服务线程”,在没有用户线程可服务时会自动离开。


试过getName、getCanonicalName、getSimpleName的区别吗?


方法 值

getName my.ExternalClassConfig

getCanonicalName my.ExternalClassConfig

getSimpleName ExternalClassConfig

getName my.ExternalClassConfig$InternalConfig

getCanonicalName my.ExternalClassConfig.InternalConfig

getSimpleName InternalConfig


getName()返回的是虚拟机里面的class的表示,而getCanonicalName()返回的是更容易理解的表示。其实对于大部分class来说这两个方法没有什么不同的。但是对于array或内部类来说是有区别的。


方法                 值
getName            [Ljava.lang.String;
getCanonicalName   java.lang.String[]
getSimpleName      String[]
相关文章
|
6月前
|
存储 安全 Java
Java大数据面试复习30天冲刺 - 日积月累,每日五题【Day03】——JavaSE
Java大数据面试复习30天冲刺 - 日积月累,每日五题【Day03】——JavaSE
67 0
|
6月前
|
安全 Java 大数据
Java大数据面试复习30天冲刺 - 日积月累,每日五题【Day01】——JavaSE
Java大数据面试复习30天冲刺 - 日积月累,每日五题【Day01】——JavaSE
74 0
|
开发框架 分布式计算 Java
【面试题精讲】JavaSe和JavaEE的区别
【面试题精讲】JavaSe和JavaEE的区别
|
6月前
|
缓存 NoSQL Java
JavaSE面试题(一)
JavaSE面试题(一)
JavaSE面试题(一)
|
6月前
|
存储 前端开发 算法
毕业季--JavaSE高级面试题
毕业季--JavaSE高级面试题
|
6月前
|
Java 大数据
Java大数据面试复习30天冲刺 - 日积月累,每日五题【Day04】——JavaSE
Java大数据面试复习30天冲刺 - 日积月累,每日五题【Day04】——JavaSE
64 0
|
6月前
|
存储 安全 Java
Java大数据面试复习30天冲刺 - 日积月累,每日五题【Day02】——JavaSE
Java大数据面试复习30天冲刺 - 日积月累,每日五题【Day02】——JavaSE
56 0
|
6月前
|
安全 JavaScript Java
JavaSE面试题(二)
JavaSE面试题(二)
|
XML 安全 Java
JavaSE基础面试题(精简版)
把CPU处理器与操作系统的整体叫平台
42 0
|
Java 大数据
Java大数据面试复习30天冲刺 - 日积月累,每日五题【Day04】——JavaSE
线程的生命周期:线程要经历新建、就绪、运行(活动)、阻塞和死亡五种不同的状态。这五种状态都可以通过Thread类中的方法进行控制。
104 0