每天一个面经系列--面经001:阿里实习面经(现场面)

一面 

面试官拿着简历先大概看了一下,然后让我自我介绍,我介绍完,他就把简历放在我的右手边。(这个细节标志着:开始进入疯狂你问我答模式啦)

1.  ArrayList 与 LinkedList 的区别 。

答:我说一个类似数组 一个类似链表。

问:那你画一下数组怎么在内存中存储的 ?

问:ArrayList 可以根据下标查找, 那LinkedList可以吗?

问:ArrayList 初始容量,如果满了会怎么办? 怎么扩容?是新建一个2倍空间的数组然后把值复制进去么?

异同点:

底层分析参考(感谢博主):https://crossoverjie.top/JCSprout/#/collections/ArrayList 

  1. 线程安全方面:ArrayList和LinkedList都是不同步的,也就是不能保证线程安全。
  2. 底层数据结构:ArrayList底层使用的是Object数组;LinkedList底层使用的是双向链表(JDK1.6之前是循环链表)
  3. 插入和删除是否收到元素位置影响:ArrayList采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响时间复杂度接近O(n);LinkedList采用链表存储,所以插入、删除元素时间复杂度不受位置的影响,都是接近O(1)。
  4. 是否支持快速随机访问:LinkedList不支持高效的随机元素访问,而ArrayList支持。快速随机访问就是通过元素的序号快速获取元素对象(对应于get(int index)方法)。
  5. 内存空间占用:ArrayList的空间浪费主要提现在:在list列表的结尾回预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗比ArrayList更多的空间(因为要存放直接后继和直接前驱以及数据)

 Java中数组在内存中的存储:


2. 给一棵树,左右子树交换,在纸上手写出来。这考察的就是平时的积累和临场发挥了

 

/**
定义二叉树TreeNode类
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
//具体实现
//递归,自定义swap方法
public class Solution {
    public void Mirror(TreeNode root) {
        if(root ==null)
            return ;
        swap(root);
        Mirror(root.left);
        Mirror(root.right);
    }
    
    private void swap(TreeNode node){
        TreeNode treeNode = node.left;
        node.left = node.right;
        node.right = treeNode;
    }
}

3.用过哪些容器,Tomcat 知道吧,说说Tomcat给你提供了哪些服务,为什么要用它?自己写一个不行吗?(这个真是一头雾水啊)

 


4.Top N 问题 ,M个数 找出最大的N个 (数的取值 0 ~ 65535)。

答:如果M比较小的话可以先排序,用效率高的 快排或者归并,然后取出前N个就可以了。若 M比较大的话,可以先把数据分成若干份(K份)  ,每份M/K 个数 维护一个含N个数的小顶堆(他很疑惑 小顶堆?),这样先求出 每份的Top N, 最后对这 K*N 个数 筛选选出 最大的N个

追问:你总体的时间复杂度是多少 ? 我当时回答的是 将复杂度相加: K*  (M/K)Log (M/K) + (K*N)Log(K*N)  ,总感觉不对 !

追问:还有更高效的方法吗?

答: 基于 数的取值是 0 ~ 65535的整数 ,可以用牺牲空间换取时间的方法,维护一个长度是65536的数组array,遍历M个数 相应数值对应的数组下标 所在的内容+1 , 比如 遍历当前值是100,那么array[100]++; 这样数组中存的值表示每个数出现的次数。最后从往前扫描数组array,累加求和sum与N比较即可得到。

追问:这种方法的时间复杂度是多少? O(M)    PS:大家要注重那个时间复杂度的练习啊

追问: 那要是 数的取值是浮点数呢? 0.0,蒙逼了

 


5. 操作系统页面置换LRU 知道吧。讲一讲 !这个平时肯定练过,由于有点紧张答得不好,建议大家好好掌握这些基础知识。LRU还没完: 具体怎么实现知道么? 我说了频率和记录时间先后,他继续追问 我就摇头了。

 


6. 基于上个问题,如果多个线程请求,你会怎么处理?我说用ConcurentLinkedQueue ,跟他讲了下结构,具体实现策略不知道。

他说可以这样 假如1000个线程,多整几个队列 假设8个,那么并发量减少到1000/8 ,设成100个队列 并发更少。至于哪个线程分到哪个队列,可以用hash的方法 将线程分散开。

 


7.数据库里有个表,tab_demo( id , data) id是主键 , 对于 where id=' 1 ' 和 where data = ' text ' ,数据库是怎么去操作的,我当时灵光一现 这肯定是考数据库索引的知识,我答到:前者数据库默认建立了Unique索引,直接根据索引能找到相应的数据,后边的要全表扫描。

追问: 如果在data 上也建立索引呢,怎么获取数据 然后时间复杂度是多少? 我就跟他讲了讲B+树索引。后边的我真心蒙逼 还是学得不够深啊

 


8. 多线程中锁,如何处理呢?保证效率。我跟他说的是 ConcurrentHashMap , 锁分段技术 Segment ,并与 HashMap、HashTable对照着阐述了一下自己的观点,他也问了几个基本参数 看我是不是真知道。

 


然后面试官让我去 外边的休息区 等,一面好像就这么多,具体的细节可能有遗漏。

二面(大概30分钟)

先还是自我介绍。

1.  你这项目用到了struts2 , 那你说一下struts1 与 struts2 的区别在哪里?这个问题我真是没想到啊

 


2.  java 设计模式知道吧,那你手写一个单例模式吧。 我先写了一个饱汉模式的,他说另外一种! 然后写了一个饿汉模式  带锁的双重检查

单例模式可能是代码最少的模式了,但是代码少并不一定意味着简单

七种写法:

 

  • 立即加载/“饿汉模式”,是在调用方法前,实例已经被创建了。
  • 缺点:不能有其他实例变量,因为getInstance()方法没有同步,所以有可能出现非线程安全的问题
public class Singleton {
    private static Singleton instance = new Singleton();

    private Singleton(){
    }

    public static Singleton getInstance() {
        return instance;
    }
}
  • 延迟加载/“懒汉模式”,线程不安全,是在调用方法时实例才被创建。
  • 缺点:在多线程中不能实现保持单例的状态。
public class Singleton {
    private static Singleton instance;

    private Singleton(){
    }

    public static Singleton getInstance() {
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}
  •  懒汉模式,线程安全
  • 此方法加入了同步synchronized关键字得到相同实例的对象,但此种方法的运行效率低下,是同步运行的,下一个线程想要取得对象,则必须等上一个线程释放锁后,才能继续执行。
public class Singleton {
    private static Singleton instance;

    private Singleton() {
    }

    synchronized public static Singleton getInstance() {

        if(instance ==null){
            instance = new Singleton();
        }
        return instance;
    }
}
  • 同步代码块
  • 效率一样很低,全部代码被上锁。

 

  • DCL双检查锁机制
  • 成功解决“懒汉模式”遇到多线程的问题。DCL也是大多数多线程结合单例模式使用的解决方案。
public class Singleton {
    //使用volatile关键字,确保当instance对象被初始化成为Singleton实例时,多线程可以正确地处理instance变量
    private volatile static Singleton instance;

    private Singleton() {
    }
    //使用双检查机制来解决问题,既保证了不需要同步代码的异步执行性
    //又保证了单例的效果
    public static Singleton getInstance() {

        if(instance ==null){//第一次检查
            synchronized (Singleton.class){
                if(instance == null){//第二次检查
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

3.  数据库连接池知道么,用的啥连接池,原理是啥? 这个问题应该是我今天最大的败笔。我说用了cp30 ,原理我真是一团浆糊 0.0让我哭会

 


4.  你做的网站并发量是多少,怎么解决的。加行锁和客观控制法

 


5.  你项目中遇到的最难的问题,怎么解决的? 这个也是回答失败的点。

 


6.  事务Transaction 知道吧,都有些什么特性?说说脏读吧! 我说了 ACID ,脏读也是紧张的忘了 0.0好失败啊

 


7.  谈谈对Hadoop 的理解,我说了大概说了下  HDFS、Map Reduce、Hbase、Hive ,然后说毕设的思路(毕设是基于分布式的)

 


8.  你们寝室有几个人? 都是什么样的人? (这个问题感觉是个陷阱啊 )

不要妄加评判,可以说他们都是很勤奋好学的人,研究方向都是什么,平常大家都在一起研究自己的目前所做的项目难点

 


9.  有什么问题想问我的?(给这次面试简单评价一下呗,面试官说:你的知识面很广,但是得在某一个方向深入研究下)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值