java面试大全

语言基础

Java的数据结构相关的类实现原理

一、 集合框架

  • 以下简单模拟一个数据结构的连环炮。
    比如,面试官先问你HashMap是不是有序的?
    你肯定回答说,不是有序的。那面试官就会继续问你,有没有有顺序的Map实现类?
    你如果这个时候说不知道的话,那这个问题就到此结束了。如果你说有TreeMap和LinkedHashMap。

那么面试官接下来就可能会问你,TreeMap和LinkedHashMap是如何保证它的顺序的?

  • Vector和ArrayList有什么不同?
    Vector和ArrayList在使用上非常相似,都可用来表示一组数量可变的对象应用的集合,并且可以随机地访问其中的元素。 Vector的方法都是同步的(Synchronized),是线程安全的(thread-safe),而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好。 当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍(如果没有指定增加系数),而ArrayList只增加50%的大小,这样,ArrayList就有利于节约内存空间。
  • hashtable和hashmap的区别,hashmap的内部实现机制,hash是怎样实现的,什么时候rehash?
    HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
    HashMap的数据结构:HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。HashMap底层就是一个数组结构,数组中的每一项又是一个链表。当新建一个HashMap的时候,就会初始化一个数组。

HashMap实现原理分析

解决hashmap的冲突

  • HashMap遍历的几种方法

二、 string、stringbuilder、stringbuffer区别

StringBuffer
Java.lang.StringBuffer线程安全的可变字符序列。一个类似于String的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。

可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。

StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。

例如,如果 z 引用一个当前内容是“start”的字符串缓冲区对象,则此方法调用 z.append(“le”) 会使字符串缓冲区包含“startle”,而 z.insert(4, “le”) 将更改字符串缓冲区,使之包含“starlet”。

简要的说,String类型和 StringBuffer类型的主要性能区别其实在于 String是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后,JVM的GC就会开始工作,那速度是一定会相当慢的。

而如果是使用StringBuffer类则结果就不一样了,每次结果都会对StringBuffer对象本身进行操作,而不是生成新的对象,再改变对象引用。所以在一般情况下我们推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。而在某些特别情况下,String对象的字符串拼接其实是被JVM解释成了StringBuffer对象的拼接,所以这些时候String对象的速度并不会比StringBuffer对象慢,而特别是以下的字符串对象生成中,String效率是远要比StringBuffer快的:

String S1 = “This is only a” + “ simple” + “ test”;

StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”); 你会很惊讶的发现,生成 String S1 对象的速度简直太快了,而这个时候 StringBuffer 居然速度上根本一点都不占优势。其实这是 JVM 的一个把戏,在 JVM 眼里,这个 String S1 = “This is only a” + “ simple” + “test”; 其实就是: String S1 = “This is only a simple test”; 所以当然不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的 String 对象的话,速度就没那么快了,譬如: String S2 = “This is only a”; String S3 = “ simple”; String S4 = “ test”; String S1 = S2 +S3 + S4; 这时候 JVM 会规规矩矩的按照原来的方式去做

在大部分情况下 StringBuffer > String

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

在大部分情况下 StringBuilder > StringBuffer

泛型

  • 有关泛型的问题(java中那些地方用到泛型,泛型的好处,举例说出泛型的好处)
    答:java 泛型是java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法

范型好处:
类型安全。 泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。没有泛型,这些假设就只存在于程序员的头脑中(或者如果幸运的话,还存在于代码注释中)。

消除强制类型转换。 泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。

潜在的性能收益。 (编译器优化)

泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,程序员会指定这些强制类型转换)插入生成的字节码中。但是更多类型信息可用于编译器这一事实,为未来版本的 JVM 的优化带来可能。由于泛型的实现方式,支持泛型(几乎)不需要 JVM 或类文件更改。所有工作都在编译器中完成,编译器生成类似于没有泛型(和强制类型转换)时所写的代码,只是更能确保类型安全而已。

equals和hashcode这些方法怎么使用的
http://blog.csdn.net/tiantiandjava/article/details/46988461

作用域

java开发框架

spring

  • spring中类加载机制?

  • Spring ioc你的理解,ioc容器启动的过程是什么样的,什么是ioc,aop 你个人的理解是什么

  • spring里面的action 默认是单列的,怎么配置成多列?

spring mvc

视频教程

servlet

servlet 默认是线程安全的吗,为什么不是线程安全的
http://westlifesz.iteye.com/blog/49511
http://jsjxqjy.iteye.com/blog/1563249
http://developer.51cto.com/art/200907/133827.htm

Servlet生命周期
http://blog.csdn.net/luwei42768/archive/2008/10/31/3191455.aspx

jsp里边的对象,以及常用的方法

多线程

多线程

  1. 多线程,高并发怎么结合业务来讲?

  2. 线程的几种状态?

  3. 线程池的实现原理,用到的数据结构,如何调度池内资源

  4. 线程池是怎么配置的,怎么用的,要注意哪些,说下个人的理解

  5. 并发问题,锁,怎么处理死锁,脏数据处理?

  6. sychronized 机制加了static方法的同步异同,A 调用 B,A执行完了,B没执行完,怎么解决这个同步问题

  7. 进程间通信的题目?
    http://blog.sina.com.cn/s/blog_4e2e15fd0100rjtn.html

  1. 什么导致线程阻塞(58、美团)

线程的阻塞

为了解决对共享存储区的访问冲突,Java 引入了同步机制,现在让我们来考察多个线程对共享资源的访问,显然同步机制已经不够了,因为在任意时刻所要求的资源不一定已经准备好了被访问,反过来,同一时刻准备好了的资源也可能不止一个。为了解决这种情况下的访问控制问题,Java 引入了对阻塞机制的支持.

阻塞指的是暂停一个线程的执行以等待某个条件发生(如某资源就绪),学过操作系统的同学对它一定已经很熟悉了。Java 提供了大量方法来支持阻塞,下面让我们逐一分析。

sleep() 方法:sleep() 允许 指定以毫秒为单位的一段时间作为参数,它使得线程在指定的时间内进入阻塞状态,不能得到CPU 时间,指定的时间一过,线程重新进入可执行状态。 典型地,sleep() 被用在等待某个资源就绪的情形:测试发现条件不满足后,让线程阻塞一段时间后重新测试,直到条件满足为止。
suspend() 和 resume() 方法:两个方法配套使用,suspend()使得线程进入阻塞状态,并且不会自动恢复,必须其对应的resume() 被调用,才能使得线程重新进入可执行状态。典型地,suspend() 和 resume() 被用在等待另一个线程产生的结果的情形:测试发现结果还没有产生后,让线程阻塞,另一个线程产生了结果后,调用 resume() 使其恢复。
yield() 方法:yield() 使得线程放弃当前分得的 CPU 时间,但是不使线程阻塞,即线程仍处于可执行状态,随时可能再次分得 CPU 时间。调用 yield() 的效果等价于调度程序认为该线程已执行了足够的时间从而转到另一个线程.
wait() 和 notify() 方法:两个方法配套使用,wait() 使得线程进入阻塞状态,它有两种形式,一种允许 指定以毫秒为单位的一段时间作为参数,另一种没有参数,前者当对应的 notify() 被调用或者超出指定时间时线程重新进入可执行状态,后者则必须对应的 notify() 被调用.
初看起来它们与 suspend() 和 resume() 方法对没有什么分别,但是事实上它们是截然不同的。区别的核心在于,前面叙述的所有方法,阻塞时都不会释放占用的锁(如果占用了的话),而这一对方法则相反。

上述的核心区别导致了一系列的细节上的区别。

首先,前面叙述的所有方法都隶属于 Thread 类,但是这一对却直接隶属于 Object 类,也就是说,所有对象都拥有这一对方法。初看起来这十分不可思议,但是实际上却是很自然的,因为这一对方法阻塞时要释放占用的锁,而锁是任何对象都具有的,调用任意对象的 wait() 方法导致线程阻塞,并且该对象上的锁被释放。而调用 任意对象的notify()方法则导致因调用该对象的 wait() 方法而阻塞的线程中随机选择的一个解除阻塞(但要等到获得锁后才真正可执行)。

其次,前面叙述的所有方法都可在任何位置调用,但是这一对方法却必须在 synchronized 方法或块中调用,理由也很简单,只有在synchronized 方法或块中当前线程才占有锁,才有锁可以释放。同样的道理,调用这一对方法的对象上的锁必须为当前线程所拥有,这样才有锁可以释放。因此,这一对方法调用必须放置在这样的 synchronized 方法或块中,该方法或块的上锁对象就是调用这一对方法的对象。若不满足这一条件,则程序虽然仍能编译,但在运行时会出现IllegalMonitorStateException 异常。

wait() 和 notify() 方法的上述特性决定了它们经常和synchronized 方法或块一起使用,将它们和操作系统的进程间通信机制作一个比较就会发现它们的相似性:synchronized方法或块提供了类似于操作系统原语的功能,它们的执行不会受到多线程机制的干扰,而这一对方法则相当于 block 和wakeup 原语(这一对方法均声明为 synchronized)。它们的结合使得我们可以实现操作系统上一系列精妙的进程间通信的算法(如信号量算法),并用于解决各种复杂的线程间通信问题。

关于 wait() 和 notify() 方法最后再说明两点:

第一:调用 notify() 方法导致解除阻塞的线程是从因调用该对象的 wait() 方法而阻塞的线程中随机选取的,我们无法预料哪一个线程将会被选择,所以编程时要特别小心,避免因这种不确定性而产生问题。

第二:除了 notify(),还有一个方法 notifyAll() 也可起到类似作用,唯一的区别在于,调用 notifyAll() 方法将把因调用该对象的 wait() 方法而阻塞的所有线程一次性全部解除阻塞。当然,只有获得锁的那一个线程才能进入可执行状态。

谈到阻塞,就不能不谈一谈死锁,略一分析就能发现,suspend() 方法和不指定超时期限的 wait() 方法的调用都可能产生死锁。遗憾的是,Java 并不在语言级别上支持死锁的避免,我们在编程中必须小心地避免死锁。

以上我们对 Java 中实现线程阻塞的各种方法作了一番分析,我们重点分析了 wait() 和 notify() 方法,因为它们的功能最强大,使用也最灵活,但是这也导致了它们的效率较低,较容易出错。实际使用中我们应该灵活使用各种方法,以便更好地达到我们的目的。

  1. 关于多线程锁问题
    最近在学习Java多线程设计的时候,在网上看到一个面试题目的讨论,虽然楼主所说有些道理,但感觉还是有些问题,故此在和同事讨论以后还是有了若干收获,在此略作总结。

首先,来看看这个面试题目吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MyStack {
private List<String> list = new ArrayList<String>();
public synchronized void push(String value) {
synchronized (this) {
list.add(value);
notify();
}
}
public synchronized String pop() throws InterruptedException {
synchronized (this) {
if (list.size() <= 0) {
wait();
}
return list.remove(list.size() - 1);
}
}
}

问题: 这段代码大多数情况下运行正常,但是某些情况下会出问题。什么时候会出现什么问题?如何修正?

代码分析:

从整体上,在并发状态下,push和pop都使用了synchronized的锁,来实现同步,同步的数据对象是基于List的数据;大部分情况下是可以正常工作的。

问题描述:

状况1:

假设有三个线程: A,B,C. A 负责放入数据到list,就是调用push操作, B,C分别执行Pop操作,移除数据。

首先B先执行,于pop中的wait()方法处,进入waiting状态,进入等待队列,释放锁。

A首先执行放入数据push操作到List,在调用notify()之前; 同时C执行pop(),由于synchronized,被阻塞,进入Blocked状态,放入基于锁的等待队列。注意,这里的队列和2中的waiting等待队列是两个不同的队列。

A线程调用notify(),唤醒等待中的线程A。

如果此时, C获取到基于对象的锁,则优先执行,执行pop方法,获取数据,从list移除一个元素。

然后,A获取到竞争锁,A中调用list.remove(list.size() - 1),则会报数据越界exception。

状况2:

相同于状况1

B、C都处于等待waiting状态,释放锁。等待notify()、notifyAll()操作的唤醒。

存在被虚假唤醒的可能。

何为虚假唤醒?

虚假唤醒就是一些obj.wait()会在除了obj.notify()和obj.notifyAll()的其他情况被唤醒,而此时是不应该唤醒的。

解决的办法是基于while来反复判断进入正常操作的临界条件是否满足

1
2
3
4
5
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}

如何修复问题?

使用可同步的数据结构来存放数据,比如LinkedBlockingQueue之类。由这些同步的数据结构来完成繁琐的同步操作。

双层的synchronized使用没有意义,保留外层即可。

将if替换为while,解决虚假唤醒的问题。

  1. 实战
    Java并发包当中的类,它们都有哪些作用,以及它们的实现原理,这些类就是java.concurrent包下面的。与上面一样,咱们也简单的模拟一个并发包的连环炮。

比如面试官可能会先问你,如果想实现所有的线程一起等待某个事件的发生,当某个事件发生时,所有线程一起开始往下执行的话,有什么好的办法吗?

这个时候你可能会说可以用栅栏(Java的并发包中的CyclicBarrier),那么面试官就会继续问你,你知道它的实现原理吗?

如果你继续回答的话,面试官可能会继续问你,你还知道其它的实现方式吗?

如果你还能说出很多种实现方式的话,那么继续问你,你觉得这些方式里哪个方式更好?

如果你说出来某一个方式比较好的话,面试官依然可以继续问你,那如果让你来写的话,你觉得还有比它更好的实现方式吗?

如果你这个时候依然可以说出来你自己更好的实现方式,那么面试官肯定还会揪着这个继续问你。

jvm相关

jvm

  1. jvm性能调优都做了什么
  2. 写代码分别使得JVM的堆、栈和持久代发生内存溢出(栈溢出)
  3. java的内存管理
  4. 画了jvm体系结构,讲解了jvm各个组件和组件的交互、GC算法、各种垃圾收集器、运行期优化、产品中遇到的与jvm相关的问题如oom、ClassLoader问题等,并针对HotSpot VM的实现讲解了堆、非堆内存划分
  5. 介绍GC,并且问是否有手动垃圾回收方法?

GC

一个GC部分简单的连环炮。

面试官可以先问你什么时候一个对象会被GC?

接着继续问你为什么要在这种时候对象才会被GC?

接着继续问你GC策略都有哪些分类?

你如果说出来了,继续问你这些策略分别都有什么优劣势?都适用于什么场景?

你继续说出来了以后,给你举个实际的场景,让你选择一个GC策略?

你如果选出来了,继续问你,为什么要选择这个策略

答:

将应用程序可用的堆空间分为分为年轻代(Young Generation)和老年代(Old Generation),又将年轻代分为Eden区(Eden Space)、From区和To区,新建对象总是在Eden区中被创建,当Eden区空间已满,就触发一次Young GC(Garbage Collection,垃圾回收),将还被使用的对象复制到From区,这样整个Eden区都是未被使用的空间,可供继续创建对象,当Eden区再次用完,再触发一次Young GC,将Eden区和From区还在被使用的对象复制到To区,下次Young GC则是将Eden区和To区还被使用的对象复制到From区。因此,经过多次Young GC,某些对象会在From区和To区多次复制,如果超过某个阀值对象还未被释放,则将该对象复制到Old Generation。如果Old Generation空间也已用完,那么就会触发Full GC(全量回收),全量回收会对系统性能产生较大影响。

GC是在什么时候,对什么东西,做了什么事情?

第一个问题:“什么时候?”
能说明minor gc/full gc的触发条件、OOM的触发条件,降低GC的调优的策略。
分析:列举一些我期望的回答:eden满了minor gc,升到老年代的对象大于老年代剩余空间full gc,或者小于时被HandlePromotionFailure参数强制full gc;gc与非gc时间耗时超过了GCTimeRatio的限制引发OOM,调优诸如通过NewRatio控制新生代老年代比例,通过MaxTenuringThreshold控制进入老年前生存次数等……能回答道这个阶段就会给我带来比较高的期望了,当然面试的时候正常人都不会记得每个参数的拼写,我自己写这段话的时候也是翻过手册的。回答道这部分的小于2%。

第二个问题:“对什么东西?”
从gc root搜索不到,而且经过第一次标记、清理后,仍然没有复活的对象。
当一个对象到GC Roots不可达时,在下一个垃圾回收周期中尝试回收该对象,如果该对象重写了finalize()方法,并在这个方法中成功自救(将自身赋予某个引用),那么这个对象不会被回收。但如果这个对象没有重写finalize()方法或者已经执行过这个方法,也自救失败,该对象将会被回收。

第三个问题:“做什么事情?”
新生代做的是复制清理、from survivor、to survivor是干啥用的、老年代做的是标记清理、标记清理后碎片要不要整理、复制清理和标记清理有有什么优劣势等。
还能讲清楚串行、并行(整理/不整理碎片)、CMS等搜集器可作用的年代、特点、优劣势,并且能说明控制/调整收集器选择的方式。

类加载机制

下面是关于类加载机制的简单连环炮。

首先肯定是先问你Java的类加载器都有哪些?

回答了这些以后,可能会问你每个类加载器都加载哪些类?

说完以后,可能会问你这些类加载之间的父子关系是怎样的?

你在回答的时候可能会提到双亲委派模型,那么可以继续问你什么是双亲委派模型?

你解释完了以后,可能会继续问你,为什么Java的类加载器要使用双亲委派模型?

你回答完以后,可能会继续问你如何自定义自己的类加载器,自己的类加载器和Java自带的类加载器关系如何处理?

内存模型

来一个关于内存的连环炮。

首先肯定就是问你内存分为哪几部分,这些部分分别都存储哪些数据?

然后继续问你一个对象从创建到销毁都是怎么在这些部分里存活和转移的?

接着可能会问你,内存的哪些部分会参与GC的回收?

完事以后,可能还会问你Java的内存模型是怎么设计的?

你回答了以后,还会继续问你为什么要这么设计?

问完以后,还可能会让你结合内存模型的设计谈谈volatile关键字的作用?

你在谈的时候,肯定会提到可见性,那么接着可见性这三个字,还可以继续问你并发的内容。

面试问题

  • gc机制?
    Java 垃圾回收机制最基本的做法是分代回收。内存中的区域被划分成不同的世代,对象根据其存活的时间被保存在对应世代的区域中。一般的实现是划分成3个世代:年轻、年老和永久。内存的分配是发生在年轻世代中的。当一个对象存活时间足够长的时候,它就会被复制到年老世代中。对于不同的世代可以使用不同的垃圾回收算法。进行世代划分的出发点是对应用中对象存活时间进行研究之后得出的统计规律。一般来说,一个应用中的大部分对象的存活时间都很短。比如局部变量的存活时间就只在方法的执行过程中。基于这一点,对于年轻世代的垃圾回收算法就可以很有针对性。

  • 介绍GC,并且问是否有手动垃圾回收方法?
    GC是垃圾收集的意思(Gabage Collection), 内存处理是编程人员容易出现问题的地方, 忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃, Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的, Java语言没有提供释放已分配内存的显示操作方法.

程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行.

一个GC部分简单的连环炮。

  • 面试官可以先问你什么时候一个对象会被GC?
    通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象。通过这种方式确定哪些对象是”可达的”, 哪些对象是”不可达的”.当GC确定一些对象为”不可达”时(比如设置为 null),GC就有责任回收这些内存空间

  • 接着继续问你为什么要在这种时候对象才会被GC?

  • 接着继续问你GC策略都有哪些分类?

  • 你如果说出来了,继续问你这些策略分别都有什么优劣势?都适用于什么场景?

  • 你继续说出来了以后,给你举个实际的场景,让你选择一个GC策略?

  • 你如果选出来了,继续问你,为什么要选择这个策略?

下面是关于类加载机制的简单连环炮。

首先肯定是先问你Java的类加载器都有哪些?

回答了这些以后,可能会问你每个类加载器都加载哪些类?

说完以后,可能会问你这些类加载之间的父子关系是怎样的?

你在回答的时候可能会提到双亲委派模型,那么可以继续问你什么是双亲委派模型?

你解释完了以后,可能会继续问你,为什么Java的类加载器要使用双亲委派模型?

你回答完以后,可能会继续问你如何自定义自己的类加载器,自己的类加载器和Java自带的类加载器关系如何处理?

再来一个关于内存的连环炮。

首先肯定就是问你内存分为哪几部分,这些部分分别都存储哪些数据?

然后继续问你一个对象从创建到销毁都是怎么在这些部分里存活和转移的?

接着可能会问你,内存的哪些部分会参与GC的回收?

完事以后,可能还会问你Java的内存模型是怎么设计的?

你回答了以后,还会继续问你为什么要这么设计?

问完以后,还可能会让你结合内存模型的设计谈谈volatile关键字的作用?

你在谈的时候,肯定会提到可见性,那么接着可见性这三个字,还可以继续问你并发的内容。

jvm性能调优都做了什么?

  • in-jvm(必考)以及jmm缓存模型如何调优 ?

  • 熟练掌握jvm(sun hotspot和ibm j9)内存模型、gc垃圾回收调优等技能

  • java虚拟机的特性(百度、乐视)
    Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用模式Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。

nio/io

http://tech.meituan.com/nio.html
http://www.cnblogs.com/LBSer/p/4622749.html

IO

IO包和NIO包的内容相对来说不是很多,首先NIO模型要熟悉,特别是其中的selector一定要非常清楚它的职责和实现原理。其实NIO的核心是IO线程池,一定要记住这个关键点。有的时候,面试官可能也会问你IO包的设计模式(装饰器模式),为什么要这样设计?

有的面试官还会问你有没有更好的设计,这个时候如果你不知道请果断说自己现在的水平有限,想不出来更好的设计,千万不要信口开河,随意YY。

java底层是怎样对文件操作的
http://www.oschina.net/code/snippet_2251389_43244

用java扫描指定文件夹下面所有以.txt, .log结尾的文件,并将其绝对路径输出。

网络编程

协议

  1. https处理的一个过程,对称加密和非对称加密
  2. socket 是用的什么协议,tcp协议连接(握手)的过程是什么样的,socket使用要注意哪些问题
      解答:tcp协议,   

    TCP

    TCP 协议可靠性数据传输实现基本原理
    TCP 协议必须提供对所有这些问题的解决方案方可保证其所声称的数据可靠性传输。TCP协议规范和当前绝大多数TCP 协议实现代码均采用数据重传和数据确认应答机制来完成TCP 协议的可靠性数据传输。数据超时重传和数据应答机制的基本前提是对每个传输的字节进行编号,即我们通常所说的序列号。数据超时重传是发送端在某个数据包发送出去,在一段固定时间后如果没有收到对该数据包的确认应答,则(假定该数据包在传输过程中丢失)重新发送该数据包。而数据确认应答是指接收端在成功接收到一个有效数据包后,发送一个确认应答数据包给发送端主机,该确认应答数据包中所包含的应答序列号即指已接收到的数据中最后一个字节的序列号加1,加1 的目的在于指出此时接收端期望接收的下一个数据包中第一个字节的序列号。数据超时重传和数据确认应答以及对每个传输的字节分配序列号是TCP 协议提供可靠性数据传输的核心本质。

TCP 协议声称可靠性数据传输,其底层实现机制主要包括三个方面:使用序列号对传输的数据进行编号,数据超时重传,数据确认应答。

12.TCP 协议建立连接的必要性 使用TCP 协议必须首先建立一个连接是保证TCP 协议可靠性数据传输的基本前提。 诚如前文所述,序列号的使用对于 TCP 协议而言至关重要,在正式数据传输之前,双方必须得到对方的初始字节数据的编号,这样才有可能对其所接收数据的合法性进行判断,才有其它的对数据重复,数据重叠等一系列问题的进一步判别和解决。故交换各自的初始序列号必须在正式数据传输之前完成,我们美其名曰这个过程为连接建立过程。

要关注的问题。

初始序列号的交换从最直接的角度来说需要四个数据包:

1> 主机 A 向主机B 发送其初始序列号。

2> 主机 B 向主机A 确认其发送的初始序列号。

3> 主机 B 向主机A 发送其初始序列号。

4> 主机 A 向主机B 确认其发送的初始序列号。

tcp头部都什么东西,http呢?

运行环境

运行环境

操作系统Linux

熟悉linux下的开发么?

  1. 负载均衡的原理
  2. 集群如何同步会话状态
  3. 用什么命令查找某个文件名?
  4. 用什么命令删除某个文件和下面的所有东西?

服务器集群有搭建过吗
http://www.iteye.com/topic/1119823

Tomcat

Tomcat最大连接数问题 tomcat 本身没有限制,可以随意配置, 不过win2000本身的限制是2000, Linux是1500, 一台普通服务器基本不能负载这么高的并发量,尤其动态应用,所以设置高了基本没有意义

tomact 里session共享是怎么做到的
http://zhli986-yahoo-cn.iteye.com/blog/1344694

Tomcat的server.xml中Context元素的以下参数应该怎么配合适

答曰:

maxThreads=“150” 表示最多同时处理150个连接 minSpareThreads=“25” 表示即使没有人使用也开这么多空线程等待 maxSpareThreads=“75” 表示如果最多可以空75个线程,例如某时刻有80人访问,之后没有人访问了,则tomcat不会保留80个空线程,而是关闭5个空的。

acceptCount=“100” 当同时连接的人数达到maxThreads时,还可以接收排队的连接,超过这个连接的则直接返回拒绝连接。

根据你的配置建议 maxThreads=“500” minSpareThreads=“100” 如果你的网站经常访问量都很大的话,缺省就开比较大 maxSpareThreads=“300” acceptCount=“100” 这只是说你的服务器可以支持这么多用户,但还要看你安装了哪些东西,还有你的程序是否足够高效率。

tomcat6 以下版本中的几点配置说明 如何加大tomcat连接数

在tomcat配置文件server.xml中的配置中,和连接数相关的参数有: minProcessors:最小空闲连接线程数,用于提高系统处理性能,默认值为10 maxProcessors:最大连接线程数,即:并发处理的最大请求数,默认值为75 acceptCount:允许的最大连接数,应大于等于maxProcessors,默认值为100 enableLookups:是否反查域名,取值为:true或false。为了提高处理能力,应设置为false connectionTimeout:网络连接超时,单位:毫秒。设置为0表示永不超时,这样设置有隐患的。通常可设置为30000毫秒。

其中和最大连接数相关的参数为maxProcessors和acceptCount。如果要加大并发连接数,应同时加大这两个参数。

添加tomcat管理员帐户 添加管理员账户tomcat-users.xml
6.TOMCAT内存 基本原理:JAVA程序启动时都会JVM 都会分配一个初始内存和最大内存给这个应用程序。这个初始内存和最大内存在一定程度都会影响程序的性能。比如说在应用程序用到最大内存的时候,JVM是要 先去做垃圾回收的动作,释放被占用的一些内存。 所以想调整Tomcat的启动时初始内存和最大内存就需要向JVM声明,一般的JAVA程序在运行都可以通过中-Xms -Xmx来调整应用程序的初始内存和最大内存: 如:java -Xms64m -Xmx128m application.jar.

方法1:如果是使用的tomcat_home/bin/catalina.sh(linux)或catalina.bat(win)启动的: 修改相应文件,加上下面这句: JAVA_OPTS=‘$JAVA_OPTS -server -Xmx800m -Xms512m -XX:MaxNewSize=256m -XX:MaxPermSize=256m -Djava.awt.headless=true’–ms是最小内存,mx是最大内存。这里设置最小内存为512M,最大内存为 800M。$JAVA_OPTS是保留先前设置。 CATALINA_OPTS似乎可以与JAVA_OPTS不加区别的使用。[对于catalina.bat则是如此设置: set JAVA_OPTS=-Xms1024m -Xmx1024m]

方法2:如果使用的winnt服务启动: 在命令行键入regedit,找到 HKEY_LOCAL_MACHINE–>SOFTWARE–>Apache Software Foundation–>Procrun 2.0–>Tomcat5–>Parameters的Java, 修改Options的值,新添加属性: -Xms64m -Xmx128m 或者直接修改JvmMx(最大内存)和JvmMs(最小内存)。

有人建议Xms和Xmx的值取成一样比较好,说是可以加快内存回收速度。 修改完之后,可以访问http://127.0.0.1:8080/manager/status查看内存大小。

也可以编写下面测试tomcat内存大小的jsp页面: <% Runtime lRuntime = Runtime.getRuntime(); out.println(“ BEGIN MEMORY STATISTICS
”); out.println(“Free Memory: “+lRuntime.freeMemory()+”
”); out.println(“Max Memory: “+lRuntime.maxMemory()+”
”); out.println(“Total Memory: “+lRuntime.totalMemory()+”
”); out.println(“Available Processors : “+lRuntime.availableProcessors()+”
”); out.println(” END MEMORY STATISTICS
“); %>

tomcat中的基本配置?
Tomcat的如何配置监听端口和启动内存?

数据库

mysql

  1. 数据库事务属性
  2. sql语句:创建一个table。
  3. sql语句优化怎么做的,建索引的时候要考虑什么
  4. 数据库连接池设置几个连接,是怎么处理的,说说你的理解
  5. 数据库性能优化有做么?做了些什么?遇到过那些问题?

mysql索引类型有哪些?
mysql存储引擎有哪些?
mysql语句如何优化?

mysql读写分离代码层实现

你们系统的数据库切分,按什么切?(纵向、横向)
数据库切分
http://wenku.baidu.com/view/35d6149b51e79b89680226a7.html

mongodb

momogo的特性,以及使用时需要注意的?业务上怎么用的?

solr

redis

系统架构设计

除了单例和工厂需要掌握其他的东西。

对高并发,高可用的想法?具体的做法?

为什么使用angularjs?

redis也准备一下,什么是redis?

知道技术架构的核心原则是什么?

架构师核心能力

http://blog.qiniu.com/archives/1489
https://yq.aliyun.com/articles/54376

架构设计

rpc通信和rmi区别
https://waylau.com/remote-procedure-calls/

网站性能优化都做了什么,具体的?ETag、Last-Modified、Expires、Cache-Control
分布式缓存的内存管理,如何管理和释放不断膨胀的session,memcache是否熟悉

设计模式

除了单例和工厂需要掌握其他的东西。

画出最熟悉的三个设计模式的类图

单例模式:懒汉模式和饿汉模式。

简述你所熟悉的设计模式。模拟一个应用场景,并说出你所使用的设计模式的优缺点(单例模式)

中间件技术主要涉及哪些?
分布式技术(缓存、消息系统、热部署、jmx等)?

高并发

什么是分布式框架?
《构建高性能Web站点》
《大型网站技术架构》
对高并发,高可用的想法?具体的做法?

  1. 高并发情况下,我们系统是如何支撑大量的请求的
  2. 并发、同步的接口或方法
  3. 并发访问同一条数据的时候,如何保证数据同步。

怎么搭建支持高并发的网站?
http://wulijun.github.io/2012/08/10/high-concurrency-web.html

系统设计

有个每秒钟5k个请求,查询手机号所属地的笔试题(记得不完整,没列出),如何设计算法?请求再多,比如5w,如何设计整个系统?

给定一个数组,数组中存放着线程的引用,根据该数据结构,设计一个线程池的方案,要求在取出空闲线程和归还线程的时候,复杂度为O(1),并且申请的辅助空间为常数级。

实现双链表查找相交节点。(我实现了3种方法)

面试官提出的问题

问题1:

给定一个数组,数组中存放着线程的引用,根据该数据结构,设计一个线程池的方案,要求在取出空闲线程和归还线程的时候,复杂度为O(1),并且申请的辅助空间为常数级。

回 答: 按照要求,需要在O(1)时间内放回或者取出,而且不能申请O(n)的辅助空间,但是在任务中可以有一些标记字段(isBusy<是否忙碌>,originIdx<对应数组位置下标>等)。 经过考虑,我可以这样做: 在每次取出和放回 的时候都按照顺序依次存放,但由于每个任务中都记录了数组下标,而数组对应下标都存着该任务的引用,则当任务没有按照次序归还线程时,可将该线程和另外一个正在运行着的线程位置进行互换,从而达到按顺序归还的效果,同时修改两个互换线程关于busy和所属下标的值,这样,在取出的时候可以做到按照顺序取,达到O(1),放回的时候可以按照顺序放,在O(1)的复杂度内,交换两个线程的所属位置即可解决。

面试经历:

内推的蚂蚁金福实习,电面的形式 一面:主要很开心的聊天,涉及都是简历项目中的问题,如分布式文件系统的一些基本CAP概念,自己开发负责的部分,整体的开发环境(40G Mellanox高速互连网等),时间也不长,大约20几分钟,面完感觉还不错 二面:面试的是一个女面试官,一开始也是介绍项目,但似乎她对我项目内容并不感冒,在我提到项目分布式文件系统用到一个开源bdb数据库后,转入数据库知识点的问答,最先问了个索引,由于没复习,完全忘记概念了。再然后问了死锁的条件及如何检测,死锁的四个条件大约还记得,答出来后,关于死锁的检测,由于平常并没使用啥工具,更多就是对自己遇到的gdb调试中的死锁问题做了一些简单阐述,后来才了解到数据库中有很多方法~最后问了一个大规模并发读写请求访问的问题,我强调了单点故障,负载均衡,但又没很完善地阐述解决方法~感觉思路就不跟面试官在一条线上吧,再加上没复习知识点极其薄弱,总体面试情况相当糟糕~ 面试官提出的问题

问题1: 产生死锁的条件?如何检测死锁? 回 答: 死锁的条件还是从那4个基本的互斥,部分分配,不可剥夺和环路作答。关于死锁的检测,感觉更多数据库当中的,如SQL就有不少处理手段,这个还是不太熟悉~

面试经历:

2015年1月底先进行了电话面试。 2015年2月安排到阿里总部单独面试,往返机票可报销。 面试官一共两人,都是技术主管,总共进行了2个小时。 最后确定下来我还在P5的水平,但近期只招收P6+的技术岗位,憾别阿里。 面试过程中讨论的技术范围很广,但都会跟部门职位相关。计算机底层,数据库索引,算法,SSH(Spring,Struts,Hibernate)相关原理,网络协议和优化,算法(手机9宫格输入法的实现)等都有问到。 虽然有3年工作经验,但这两个月离职阶段确实没准备好,不少问题没答到点上,虽然经过提示,还是能回答上。但阿里P6+ 级别的要求是能在个别技术领域上独当一面,所以面试过程中提示过多,那就很遗憾的只能Say good bye了。 不管怎么说,准备面试与参加面试过程中,让整个技术生涯的经验都得到了沉淀,今后发展道路也更加清晰,不虚此行。 继续加油。阿里春季确认,大伙加油吧。 面试官提出的问题

问题1: 面试中提出了几个实战型的问题,其中一个是抛开现有的开源软件,独立设计一套高并发的分布式登陆系统,要如何实现。 回 答: 从如何储存用户信息,如何同步Session,如何管理Cookie,如何避免XSS攻击,平行权限问题等方向去答(没有回答得很满意)。

1到1亿的自然数,求所有数的拆分后的数字之和,如286 拆分成2、8、6,如1到11拆分后的数字之和 => 1 + … + 9 + 1 + 0 + 1 + 1。

海量数据处理
http://mm.fancymore.com/reading/java-interview-questions2.html
http://blog.csdn.net/clam_clam/article/details/6869556

秒杀系统设计
http://mm.fancymore.com/reading/java-interview-project-killsgood.html

数据结构与算法

数据结构与算法

二叉树的遍历算法

快速排序,手写代码。
就是从一个无序数组中找出中位数,我没想到什么好方法,直接用选择排序将数组进行排序(排出前半部分就可以了),然后return a[a.length/2]

总结:快速选择可以用于这类面试题:

1)求出无序数组中第k大的数

2)求出无序数组中最大/小的k个数

参考: http://www.tuicool.com/articles/M3EnAra

堆排序,描述过程,纸上画出来。

写算法:输出一个串的所有可能字符组合。

例如输入“abcd“,输出a,b,c,d,ab,ac,ad,bc,bd,cd,abc,abd,acd,bcd,abcd 输入串可能会有重复字符,例如输入”abcc“,输出a,b,c,ab,bc,ac,cc,abc,acc,bcc

递归算法:http://bylijinnan.iteye.com/blog/1370407

二进制算法:http://zhidao.baidu.com/question/398799198.html

加密解密的东西做过么?如md5什么的

斐波那契数列
http://lavasoft.blog.51cto.com/62575/199680

关于阶乘的两个常见算法及一个相关面试题
http://www.cnblogs.com/anderslly/archive/2008/05/19/factorial-algorithms.html

《程序员面试金典》

技术团队管理

  • 团队领导能力,怎么管人?
  • 项目管理能力

敏捷管理具体是怎么做的,结合业务。

梳理项目需求怎么能保证快速准确的产出需求。

如果遇到产品和技术的工期矛盾怎么处理?

沟通能力强

团队领导能力

项目管理能力
项目管理过程有着比较深入的理解

项目管理、自动部署等工具
maven、svn、git、jenkins等

面试技巧

http://www.sunhaojie.com/2016/01/06/%E7%A8%8B%E5%BA%8F%E5%91%98%E6%80%8E%E4%B9%88%E8%8E%B7%E5%BE%97%E9%AB%98%E5%B7%A5%E8%B5%84/

自我介绍主要考察方面

套路
面试官趁机看简历
营造一个轻松的开场

你是谁?
态度
了解一些个人信息:年龄、专业、工作年限、工作经历、行业背景、项目经验
通过你的声音、肢体语言,又或是你的姓名由来,背景故事,都可以决定你的第一印象是否深刻

你会什么?
表达能力
逻辑总结能力
知识面如何,是否对技术有浓厚兴趣,特别关注的是你的特长是什么。

为什么是你?
主要考察你的能力和目标岗位的匹配度,主要以下
专业技能与特长
业务经验
是否可以融入当前团队

自我介绍和项目介绍

面试中描述你做的每一个项目:
你做了什么工作?
这些工作你解决了什么问题?
还有什么困难没有解决?
这些困难在后续如何优化?
优化后可以实现什么功能?
这些功能如何和中间件和分布式并行系统联系在一起??

==自我介绍的时候还需要准备一下,怎么突出自己的能力,技术和管理?==
结合业务来说技术点?

未来的定位是什么?偏技术或者偏管理?具体怎么规划的?你比较有优势的点?未来期望加强的点

这一部分内容,一般的模式就是你自己去讲你做过的项目,然后面试官会冷不丁的让你去解释其中某一部分,比如让你解释当时为什么要这么做,或者问你现在觉得有没有更好的办法。而这些穿插的问题,大部分与你的项目所用到的技术有关。而你需要做的,就是充分、再充分的去总结自己做过的项目(尤其是最近的一两个项目),挖掘出一个甚至N个亮点,以备于到时候可以让面试官产生眼前一亮的感觉。如果你能达到这种效果的话,基本上离你成功就不远了。

先从项目模块入手,详细问项目模块是怎么实现的,遇到的问题怎么解决(一定要说自己做过的,真实的情况)

个人优势?

与同事沟通的时候,如果遇到冲突了如何解决?

说说项目

由于我几年一直做一个产品,从后台做到前台,从业务开发做到技术平台,所以就画了整个产品部署架构图,b/s & c/s的,然后一层层的讲解。

   B/S现有Web框架改造、浏览器缓存、c/s补丁下载各种方式、cdn、c/s通信协议、rpc集群、http集群、负载均衡、集群前置机调 度、后端服务器主从实例、后端服务器各种优化(异步、性能隔离)、数据库服务器各种优化(索引、物化视图、读写分离、帐套结转、数据库横向切分、纵向切 分)、层间调用性能监控的实现,对照产品架构图各个部分一路讲下来。
  
   自我介绍是简历中最重要的。==自我介绍要用事实描述,不要用观点描述,比如我有10年Java开发经验,这个是事实,我崇尚团队合作,学习能力强,这个是观点。==事实可以证明,而观点很难,所以事实描述比观点描述更有说服力。自我介绍主要是对自己经历的一个亮点总结,比如张三有十年的Java开发经验,其中有两年的Linux操作经验,两年的项目管理经验。张三有自己的个人技术博客XXX.com,经常翻译国内网文章并在XX网站发表,主导或参与XX开源项目。曾经在XX比赛中拿过三等奖。当然类似于学习能力很强的观点描述也可以写,但是要举例子,比如曾经在2周内学习完IOS,并开发了XX应用。

  

项目管理

团队管理心得?
梳理项目需求怎么能保证快速准确的产出需求。
敏捷管理具体是怎么做的,结合业务。
如果遇到产品和技术的工期矛盾怎么处理?

敏捷开发
https://www.zhihu.com/question/20637406
http://www.ciandt.com.cn/blog/agile-advantage-weakness

管理能力
https://linux.cn/article-6356-1.html
http://developer.51cto.com/art/201603/507074.htm
http://meta.ftqq.com/groups/%E9%9A%8F%E7%AC%94/%E5%B8%9D%E9%83%BD%E6%B5%AE%E7%94%9F%E5%BD%95/_book/004.html

突出自己的技术能力

怎么达到给面试官留下深刻印象的技术深度呢?
1、一个取巧的方式是在准备面试的阶段,研究一个技术点,尽量深的挖掘,面试时如果有机会聊这个点,会有一定的效果。其实这种也不算一种取巧,技术深度的考察就是考察候选人是否有专研的能力,学习能力。研究的知识点尽量是以往项目中用到的,至于原因好好想想就明白了。

回答问题不够细致(应该是因为对技术不够深入造成的)
找几个点进行深入的研究
momogo的特性,以及使用时需要注意的?业务上怎么用的?
分片
用智联那一套东西来说

个人信息和工作经验

我叫郝伟光,86年出生, 2009年毕业于内江师范学院。 在互联网行业有超过7年的丰富的研发工作经验,4年的团队管理经验,曾先后任职于搜房网、正保教育、智联招聘和聚力精彩这几家公司,在上家公司担任研发总监的岗位兼任架构师;
热爱技术,熟悉Java技术体系,另外对.NET、iOS开发有所涉猎,擅长分布式、高性能应用的设计。负责过日pv千万级的项目。
我熟悉各种开发流程和主流架构模式,以及设计模式和UML,有较强的需求分析、架构设计、项目管理能力,对敏捷开发有较深入的理解并有多个项目成功经验,独立带领20-30人的团队进行研发.
我在研发团队管理期间,尝试了多种方法去建立良性的团队氛围,并有效的改善了研发效率;关注如何提高程序员的生产力。通过工具的使用,专业的培训学习提升技术人员水平。
技术是为产品支撑的,所以我对产品设计也有所涉猎。
在公司中曾多次别评为优秀员工。非常感谢!

项目介绍

1、项目开发能力,面试中在个人的开场白后面试官会选择一个简历中的项目或者让面试人自己选择项目描述,这里主要是检验面试人的项目能力,包括项目理解力,沟通能力和思维能力等。选择哪个项目比较合适?描述和公司的业务或者和这个职位的业务相关的项目是一个更好的选择,因为相关面试官会更了解业务,所以就要求面试人对项目的描述要更有条理。介绍整个项目的时候最好围绕以下几点描述:
1、项目的目标,项目主要解决了什么问题,是否能讲明白这点非常重要,只有说明白了问题域,才能使项目的实现更合情合理。
2、项目是怎么实现的,采用了什么技术,框架,有哪些困难,又是采用什么办法解决了?这个阶段面试人要仔细的思考一下,是主要体现能力的地方。最忌讳简单的描述实现方式是增删改查,没有难点和亮点。有句老话叫:“会者不难,难着不会”,所以当开发完成一个项目后总是发现项目没有什么难度,找不出亮点,其实是已解决的问题都会感觉到比较简单。所以做完项目后总结一下,回顾一下项目开发过程中设计的优点和缺点,挖掘一下项目的亮点,使项目更饱满。也不用回避项目中的缺点,项目没有一蹴而就的,不是所有问题都可以完美解决的,所以不妨说出项目的缺点,如果能给出一个补救措施会更好。
3、自己在团队中是什么角色,做了哪些贡献?有哪些收获?重点是哪些收获,因为以前的都是过去式,将来能在新项目做多少贡献才是重要的。所以项目中使用到的技术,框架,技巧等,如果能深入研究一下对以后的工作和面试会有比较好的帮助。

工作成绩——下边写一段实例,其中内容是虚构的:

  • 2006年,参与了手机XX网发布系统WAPCMS的开发(这部分是大家都会写的)。
  • 作为核心程序员,不但完成了网站界面、调度队列的开发工作,更提出了高效的组件级缓存系统,通过碎片化缓冲有效的提升了系统的渲染效率(这部分是很多同学忘掉的,要写出你在这个项目中具体负责的部分,以及你贡献出来的价值)。
  • 在该系统上线后,Web前端性能从10QPS提升到200QPS,服务器由10台减少到3台(通过量化的数字来增强可信度)。
  • 2008年升任WAPCMS项目负责人,带领一个3人小组支持着每天超过2亿的PV(这就是Benefit。你能带给前雇主的价值,也就是你能带给新雇主的价值)。

  1. 之前做过哪些项目;举个例子说明那个==项目的关键点、技术架构==

    一站式招聘管理平台

    关键点

架构:基于dubbo微服务架构设计,前后端分离,restful风格的接口定义
后台:spring+spring mvc+mybatis+Spring Data JPA
前台:angularjs+jquery+bootstrap
数据:mysql、redis、mongodb和solr
其他:rabbitMQ、JUnit单元测试、Jenkins自动化部署

智联招聘-校园招聘系统

架构:系统采用SOA架构设计,
主要使用到的技术spring+spring mvc+mybatis ,mysql读写分离,Mongodb,rabbitMQ,Memcached,Solr,CDN等,基于以上技术,网站在面对高并发高负载也可以保证高性能和高可用性,压力测试结果显示网站可以响应千万级别用户使用。

父母会(一个母婴类社交网站)

搜房家天下家居电商平台

这一部分内容,一般的模式就是你自己去讲你做过的项目,然后面试官会冷不丁的让你去解释其中某一部分,比如让你解释当时为什么要这么做,或者问你现在觉得有没有更好的办法。而这些穿插的问题,大部分与你的项目所用到的技术有关。而你需要做的,就是充分、再充分的去总结自己做过的项目(尤其是最近的一两个项目),挖掘出一个甚至N个亮点,以备于到时候可以让面试官产生眼前一亮的感觉。如果你能达到这种效果的话,基本上离你成功就不远了。

先从项目模块入手,详细问项目模块是怎么实现的,遇到的问题怎么解决(一定要说自己做过的,真实的情况)

由于我几年一直做一个产品,从后台做到前台,从业务开发做到技术平台,所以就画了整个产品部署架构图,b/s & c/s的,然后一层层的讲解。

B/S现有Web框架改造、浏览器缓存、c/s补丁下载各种方式、cdn、c/s通信协议、rpc集群、http集群、负载均衡、集群前置机调 度、后端服务器主从实例、后端服务器各种优化(异步、性能隔离)、数据库服务器各种优化(索引、物化视图、读写分离、帐套结转、数据库横向切分、纵向切 分)、层间调用性能监控的实现,对照产品架构图各个部分一路讲下来。

职业规划

未来方向是做技术管理,偏向于技术。

有什么问题想问的?

个人优势?

技术人员的三条路子:
技术
管理
产品管理

未来的定位是什么?偏技术或者偏管理

程序员面试所需的软技能

==那就是在一个适合思考的时刻,去思考和总结自己所经历的过去以及所掌握的技术,要总结到精髓,并且挖掘出自己至少一个亮点。==

你为什么要换工作

老大问你这个问题,就是想评估一下如果你入职之后,能待多久,公司团队能不能把你融进来。

我觉得这个问题,程序员们就不要太纠结于技巧了,直接老老实实从下面俩原因选一个或都讲,坦诚相待就OK了:

  • 钱不够,薪资没达到期望值

    • 这个大家不要避讳,HR和面试官会觉得这个原因是OK的
  • 觉得现在的工作在浪费时间,没有成就感,想找一个更牛的团队,实现自己的价值

    • 表达自己技术和职业上的追求,而不是混日子养老

注意一定不要说是因为和领导闹得不愉快,或者领导傻逼这种话,面试官要是听到这种话,内心独白就是:老子要是把你招进来,以后你背后是不是也会骂我,那赶紧滚犊子吧。然后面带微笑的说,今天的面试就先到这了,balabala……

回答完这个问题之后,最好在表达一下自己心中的技术团队的氛围,常用词汇有,开放,对事不对人,敢于尝试新技术,等等

你还有什么问题吗

最好不要回答没啥问题了,一定要问几个,显得自己对这个工作是特别渴望的,比如下面几个:

  • 咱们部门具体采用的技术方案是什么

  • 我如果能来,是一个什么角色

  • 公司未来两到三年对技术部门的规划是什么

  • 我今天面试的结果大概是怎样的,有哪些需要继续提升的

如何谈薪酬

很多程序员,包括很久之前的我,都根本不会谈薪酬,或者谈一次就放弃,别人给多少就是多少。薪酬谈判其实还是蛮重要的,不仅仅是多的那些钱,更重要的因为薪酬谈判中你如何评价自己和谈判能力,会影响公司对你的看法。

一旦成为公司的一员,其实你很难改变别人的第一印象,涨薪也是按照百分比,仔细的谈一下薪酬,可以让未来的雇主觉得你是一个很有价值的员工,就像我当年进百度,傻不呵呵的说了一句对薪资没啥要求,结果应该就是最低的工资,囧。

其实薪酬谈判是受你自己的声望和能力影响的,想一下你如果你的Github主页有2000个星星,谈判的时候的主动权会非常大,所以薪酬谈判很大一部分因素是日常的积累,就像前面说的自我营销。

获得面试机会的类型

你获取工作方式的不同,也决定的你薪酬谈判时候的地位,通常来说是 公司主动找到你>内推>猎头>自己海投,所以大家尽量找关系内推。如果有一天你的博客下面收到以下面试邀请,那你的谈判主动权会大大提高,所以还是注意日常积累吧

不要先出价

谈判一个重要法则,就是先出价的会比较处于劣势,因为你没法加价了,却给了对方砍价的空间,但是要一个过于高的价格,又会让雇主直接放弃,我的策略是,先找到自己的定位,然后再谈判

找准自己的定位

比如你特别想去A公司,你现在公司是10K,

  • 先找几个BCDE公司练练手,薪酬谈判的时候直接要高价,比如20K

  • 如果对方想也没想就拒绝了,说明自己现在还不够格,下次面试要15试试

  • 如果对方犹豫或者答应了,下次面试你就可以要25K 以此类推

目的就是找准市场给自己的定价,心里有一个谱。

具体谈判

面试官和HR一定会问你,你的薪资要求.这个时候最好的回答就是拒绝回答,面试申请单要求写期望薪资,可以写根据薪酬体系面议,面试官问你,也给出相同的答复,如果再问,可以用几个问题缓解一下,比如

  • 给出预期之前,我愿意更了解一下贵公司和我的工作内容

  • 关于这个职位,你们一定有一个具体的预算,我可以告诉你们这个预算是不是符合我心理预期

  • 我现在没法给出一个具体的数字,如果一定要的话,大概是XX到XX(就必须说出一个区间了)

  • 我手里已经有月薪15K的offer了,诸如此类,提高自己谈判的地位

参考