辞去了东软的外包工作后,我又开始了如刚毕业时的找工作环节。面试了3家公司,第一家也没问什么东西,就问了下我做过的项目,5-10分钟就把我打发了。第二家面试官不知从哪来的优越感,光是看他那装B样就不想去了。只有第3家公司让我觉得很专业,可惜人家招的职位不适合我,不是我想从事的工作。不过面试的总结还是要做一下的。

    第三家公司——美行科技,据说老板曾经也是在东软任职。后来自己创办了这家公司。我是在下班之后去这家公司面试的,那天下班时还正赶上下大雨,所以到这家公司大厦的时候我已经被浇的很是狼狈了,坐电梯到14楼时正赶山人家的员工成群结队的往外走,公司给我的第一感觉还不错,虽说没有东软的自然风光和大公司特有的工作环境,但可以看出公司的规模并不算小,我进去的巧,正赶上HR下班,她知道我来面试,就给我一套java的卷子让我去会议室里完成(1个小时时间),这份卷子有单选、多选、填空、问答、编程,答的我很吃力。

    我还记得第一道是问Java语言是由什么语言经过变更才出现的?(答案中有Ruby、C++、还有两个我没见过就没记住【百度答案: Objective-C,C,Smalltalk,Eiffel,C++】我当时选的是C++不知对错)后面考的都是java的基础知识(太多了实在没记)我就这样吃力的答着这份题(后来看了马士兵老师的关于找工作的视频才知道自己当时有多2!竟然把这个当成大学考试的卷子来答。用马老师的话说“答面试题是要考100分吗?不是!是要体现你的能力。”)我这边还没有答完,面试官就过来了问我“答的怎么样了啊?”(尼玛说好的1个小时呢?怎么才30分钟左右)“还差附加题了”我回答。

然后他就拿走了卷子。我当时觉得答的不好,所以有点不好意思的说“答的不是很好,很多基础知识记得模糊了”“恩。。是答的不怎么好”面试官随意看了看卷子就开始了技术面试。

    “你说一下String,StringBuilder和StringBuffer的区别”这个简单啊,常考啊。我回答“String 的长度不可变,StringBuilder和StringBuffer的长度可变,但是StringBuilder不够安全。”“那什么时候不安全?”我:“。。。。我都只是用StringBuffer的”“在多线程使用的时候就不安全了”

【百度答案:

在大部分情况下 StringBuffer > String
StringBuffer
Java.lang.StringBuffer线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。
可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。
StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。
例如,如果 z 引用一个当前内容是“start”的字符串缓冲区对象,则此方法调用 z.append("le") 会使字符串缓冲区包含“startle”,而 z.insert(4, "le") 将更改字符串缓冲区,使之包含“starlet”。
在大部分情况下 StringBuilder > StringBuffer

java.lang.StringBuilde
java.lang.StringBuilder一个可变的字符序列是5.0新增的。此类提供一个与 StringBuffer兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。

将 StringBuilder 的实例用于多个线程是不安全的。如果需要这样的同步,则建议使用 StringBuffer。


“那如何避免这种不安全呢?”
我:“。。。。使用同步??”“你在多线程的时候不用它就可以啦”(呵呵,你真贱)“说说线程和进程的区别”我:“。。。”“线程可以共享,进程不可以,其他的也没什么区别了吧”

【百度答案:

进程间是独立的,这表现在内存空间,上下文环境;线程运行在进程空间内。
一般来讲(不使用特殊技术)进程是无法突破进程边界存取其他进程内的存储空间;而线程由于处于进程空间内,所以同一进程所产生的线程共享同一内存空间。
同一进程中的两段代码不能够同时执行,除非引入线程。
线程是属于进程的,当进程退出时该进程所产生的线程都会被强制退出并清除。
线程占用的资源要少于进程所占用的资源。
进程和线程都可以有优先级。
在线程系统中进程也是一个线程。可以将进程理解为一个程序的第一个线程。
进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
1) 简而言之,一个程序至少有一个进程,一个进程至少有一个线程.
2) 线程的划分尺度小于进程,使得多线程程序的并发性高。
3) 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
4) 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
5) 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。


“反射机制你了解多少?”我:“我只知道是在写框架的时候用到的。”“那你说说反射的缺点。”(老子都说了了解不多还问我缺点??)我:“。。。”(这道题面试官没有给我答案)

【百度答案:

  • 性能第一 Performance Overhead

  • Because reflection involves types that are dynamically resolved, certain Java virtual machine optimizations can not be performed. Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications.

  • 反射包括了一些动态类型,所以JVM无法对这些代码进行优化。因此,反射操作的效率要比那些非反射操作低得多。我们应该避免在经常被 执行的代码或对性能要求很高的程序中使用反射。

  • 安全限制 Security Restrictions

  • Reflection requires a runtime permission which may not be present when running under a security manager. This is in an important consideration for code which has to run in a restricted security context, such as in an Applet.

  • 使用反射技术要求程序必须在一个没有安全限制的环境中运行。如果一个程序必须在有安全限制的环境中运行,如Applet,那么这就是个问题了。。

  • 内部暴露 Exposure of Internals

  • Since reflection allows code to perform operations that would be illegal in non-reflective code, such as accessing private fields and methods, the use of reflection can result in unexpected side-effects, which may render code dysfunctional and may destroy portability. Reflective code breaks abstractions and therefore may change behavior with upgrades of the platform.

  • 由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方法),所以使用反射可能会导致意料之外的副作用--代码有功能上的错误,降低可移植性。反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化。


    然后他就问我那个面试时常考的递归题就是F0 = 0, F1 =1 F2 = F0+F1的那个,我后来把我在卷子上写的程序放到Eclipse中完全没有问题,知识我使用的是ArrayList 他问我怎么使用递归的方法得到,我没回答。最后问的是编程题:一个饭店有5个厨师,一个厨师做菜用1分钟,有一个服务员,服务员上菜用30秒,有十个顾客(具体多少个顾客记不住了)每个顾客点两个菜,请把上述问题编程。话说这道题我都不知道它要什么,面试官问:“这道题你觉得应该用那种模式?”我:“。。。”“这很明显是使用生产者消费者模式啊”此外还让我说了关于二叉树,设计模式等内容。
    总之,这次美行的面试我获得的巨大失败更让我清楚的认识到面试中自己的不足。很感谢那位面试的兄弟,让我学到了这么多内容。