一家小而美的外企公司面试体验

前言

第一篇博客,呵呵,写下最近一次的面试经历吧。

2019.3月末,像我这种年轻浮躁的程序员心里的魔鬼被放了出来。跳槽!跳槽!
实际上我也有了offer,可能是offer不够吸引我吧,或者说我还有梦想。最近去了一家外企面试,公司规模不大,但是通过看简介以及跟HR沟通,觉得公司是难得遇见的优秀的公司,可能会遇到很nice很open的人。
废话多了,接入正题。

面试经历

优秀的公司HR之前跟我沟通了下午4点半去面试,多么善解人意的时间。

4点半我准时到达门口,一个女孩子坐在进门的小圆桌上抱着一个笔记本在奋笔疾书。我摁下门铃,她帮我开门,我说面试,接着她抱着电脑叫了一声赛瑞(Sarry)? 应该是这个发音。一个小巧玲珑的HR出来了,跟我稍微谈论了一下说要拿张笔试题给我做一下。拿到笔试题之后大致看了一下,5道题,非常简单
1、&与&&的区别
2、继承和实现的区别
3、多态是什么,简单解释
4、线程的实现方式
5、单例模式实现
我看到这么简单瞬间觉得有了自信,当我写完的时候看了下时间4:38,感觉一两分钟就造完了。

接下来第一轮面试,一个Java相关的技术人员,面容很老了,听说大概十多年工作经验。觉得很强。
面试官问了下面试题部分,我简单讲解了下。面试官对我写的单例模式提出了个疑问(我写的恶汉,因为代码比较简单),这个代码是否线程安全? 我心里笑了一下,这点小问题…
这个是我当时写的代码:

public class Singleton {
    private static Singleton s = new Singleton();   
    private Singleton(){    
    }
    public static Singleton getSin(){        
        return s ;
    }
}

这个代码肯定是最简单的,我是懒得写,我就把线程安全的单例给口述了一遍
一种是这个,加synchronized关键字,可以保证线程安全性。

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

但这种颗粒度比较大,直接在方法上面加了synchronized关键字,稍微会影响点效率吧。还有一种叫双重同步锁的实现方式:

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

这种方式在进入方法的时候不会加锁,进入方法后判断是否已经存在实例,不存在再创建的时候加锁,加锁之后再判断是否存在实例(有可能在加锁的过程中别的线程刚释放锁并且生成了实例,这个时候实例不为null),这种双重判断的方式对效率会有一点增益,也保证了线程安全,名曰双重同步锁的单例模式。

之后又讲了讲代理模式、策略模式。讲完之后看着面试官觉得自己有点膨胀...

面试官又问了Java8的一些新特性是否了解,我对Java8也是了解了一点点,Java8推崇函数式编程。之前看了@FunctionalInterface这个注解,该注解标注的接口只能有一个抽象方法,此接口被称为函数式接口。通过阅读这个注解的源码注释可以知道:
1、该注解只能标记在"有且仅有一个抽象方法"的接口上。
2、JDK8接口中的静态方法和默认方法,都不算是抽象方法。
3、接口默认继承java.lang.Object,所以如果接口显示声明覆盖了Object中方法,那么也不算抽象方法。
4、该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错。
讲了下lambda表达式,stream流操作。我因为之前看过一篇文章,地址:http://www.importnew.com/17262.html
我对面试官说stream流其实效率不高,看着大佬的表情泛起了疑问,哈哈哈哈。

接着面试官又问了我一些线程方面的。
1、造成死锁的原因
2、Lock与synchronized,wait与sleep
3、java并发包的了解

问了一些微服务中间件相关的,我简单讲解了一下dubbo的结构,表示理解可能不是很深刻,讲了讲redis注册服务,讲了讲做过得项目架构,以及RPC调用的几种方式。讲了讲MQ,以及延时队列的实现。讲了讲MongoDB的使用体验。大概好像也就这些,有的可能记忆不太清楚了。

第二轮面试,过一会又来一个面试官,CTO级别的。性格很open,来了就开始说你也看过flutter,我说简单涉猎一点,就开始问我一些dart的语法。

接着出了一个简单的问题:
A说B说谎,B说C说谎,C说AB都说谎,至少有一个人说谎。问谁说谎?(考离散数学命题)
试推理:
1、假设A说B说谎是真,那B说C说谎是假,C说AB都说谎是真,与原命题假设矛盾 ✖
2、假设A说B说谎是假,那B说C说谎是真,C说AB都说谎是假,AB有可能只有一个人说谎 ✔
即推理2为正确答案:A说谎,B没有说谎,C说谎。

再接下来考计算机网络相关的七层协议:
这个概念性的,我计算机网络学的一般,概念也没记全,所以当时没答完,羞愧了。
七层协议

又问了下数据库ACID
原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。
原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
一致性:一个事务可以封装状态改变(除非它是一个只读的)。事务必须始终保持系统处于一致的状态,不管在任何给定的时间并发事务有多少。
隔离性:隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。
持久性:在事务完成以后,该事务对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

大概这些吧也问了一些操作系统软件工程相关的,概念性的东西。

我比较懒的记,这可能就是此次面试吃亏的原因吧。面试的时候二面觉得自己面的不够好。基础不够扎实,面试准备不够充分。慢慢积累吧,前方道路还很长。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值