做者:bobbyparadise
连接:https://www.nowcoder.com/discuss/84899?type=0&order=4&pos=3&page=1
来源:牛客网
javascript
拼多多面试: html
1,· CHROME给每一个tab开了进程,为何? 其实就是问线程与进程区别 : java
· · 进程是具备必定独立功能的程序、它是系统进行资源分配和调度的一个独立单位,重点在系统调度和单独的单位,也就是说进程是能够独立运行的一段程序。 node
· 线程是进程的一个实体,是CPU调度和分派的基本单位,他是比进程更小的能独立运行的基本单位,线程本身基本上不拥有系统资源。在运行时,只是暂用一些计数器、寄存器和栈 。 mysql
· 调度:线程做为调度和分配的基本单位,进程做为拥有资源的基本单位。 react
· 并发性:不只进程之间能够并发执行,同一个进程的多个线程之间也能够并发执行。 linux
· 拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但能够访问隶属于进程的资源。 android
· 具体见Java线程与线程、进程与进程之间通讯方式 ios
· 关于进程和线程,首先从定义上理解就有所不一样: nginx
1. 进程是具备必定独立功能的程序、它是系统进行资源分配和调度的一个独立单位,重点在系统调度和单独的单位,也就是说进程是能够独立运行的一段程序。
2. 线程是进程的一个实体,是CPU调度和分派的基本单位,他是比进程更小的能独立运行的基本单位,线程本身基本上不拥有系统资源。在运行时,只是暂用一些计数器、寄存器和栈 。
·
他们之间的关系
·
1. 一个线程只能属于一个进程,而一个进程能够有多个线程,但至少有一个线程(一般说的主线程)。
2. 资源分配给进程,同一进程的全部线程共享该进程的全部资源。
3. 线程在执行过程当中,须要协做同步。不一样进程的线程间要利用消息通讯的办法实现同步。
4. 处理机分给线程,即真正在处理机上运行的是线程。
5. 线程是指进程内的一个执行单元,也是进程内的可调度实体。
·
从三个角度来剖析两者之间的区别
·
1. 调度:线程做为调度和分配的基本单位,进程做为拥有资源的基本单位。
2. 并发性:不只进程之间能够并发执行,同一个进程的多个线程之间也能够并发执行。
3. 拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但能够访问隶属于进程的资源。
· 共享变量
· wait/notify机制
· Lock/Condition机制
· 管道
· 线程间发送信号的一个简单方式是在共享对象的变量里设置信号值。线程A在一个同步块里设置boolean型成员变量hasDataToProcess为true,线程B也在同步块里读取hasDataToProcess这个成员变量。这个简单的例子使用了一个持有信号的对象,并提供了set和check方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public class MySignal{ protected boolean hasDataToProcess = false; public synchronized boolean hasDataToProcess(){ return this.hasDataToProcess; } public synchronized void setHasDataToProcess(boolean hasData){ this.hasDataToProcess = hasData; } } |
· 线程A和B必须得到指向一个MySignal共享实例的引用,以便进行通讯。若是它们持有的引用指向不一样的MySingal实例,那么彼此将不能检测到对方的信号。须要处理的数据能够存放在一个共享缓存区里,它和MySignal实例是分开存放的。
· 为了实现线程通讯,咱们能够使用Object类提供的wait()、notify()、notifyAll()三个方法。调用wait()方法会释放对该同步监视器的锁定。这三个方法必须由同步监视器对象来调用,这可分红两种状况:
o 对于使用synchronized修饰的同步方法,由于该类的默认实例是(this)就是同步监视器,因此能够直接调用这三使用个方法。
o 对于synchronized修饰的同步代码块,同步监视器是synchronized括号里的对象,因此必须使用该对象调用这三个方法。
·
假设系统中有两条线程,这两条线程分别表明取钱者和存钱者。如今系统有一种特殊的要求,系统要求存款者和取钱者不断的实现存款和取钱动做,并且要求每当存款者将钱存入指定帐户后,取钱者当即将钱取走.不容许存款者两次存钱,也不容许取钱者两次取钱。
咱们经过设置一个旗标来标识帐户中是否已有存款,有就为true,没有就标为false。具体代码以下:
·
·
首先咱们定义一个Account类,这个类中有取钱和存钱的两个方法,因为这两个方法可能须要并发的执行取钱、存钱操做,全部将这两个方法都修改成同步方法.(使用synchronized关键字)。
·
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
public class Account { private String accountNo; private double balance; //标识帐户中是否有存款的旗标 private boolean flag=false; public Account() { super(); } public Account(String accountNo, double balance) { super(); this.accountNo = accountNo; this.balance = balance; } public synchronized void draw (double drawAmount){ try { if(!flag){ this.wait(); }else { //取钱 System.out.println(Thread.currentThread().getName()+" 取钱:"+drawAmount); balance=balance-drawAmount; System.out.println("余额 : "+balance); //将标识帐户是否已有存款的标志设为false flag=false; //唤醒其它线程 this.notifyAll(); } } catch (Exception e) { e.printStackTrace(); } } public synchronized void deposit(double depositAmount){ try { if(flag){ this.wait(); } else{ System.out.println(Thread.currentThread().getName()+"存钱"+depositAmount); balance=balance+depositAmount; System.out.println("帐户余额为:"+balance); flag=true; //唤醒其它线程 this.notifyAll(); } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } } |
· 接下来建立两个线程类,分别为取钱和存钱线程!
· 取钱线程类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class DrawThread implements Runnable { private Account account; private double drawAmount; public DrawThread(Account account, double drawAmount) { super(); this.account = account; this.drawAmount = drawAmount; } public void run() { for(int i=0;i<100;i++){ account.draw(drawAmount); } } } |
· 存钱线程类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class depositThread implements Runnable{ private Account account; private double depositAmount; public depositThread(Account account, double depositAmount) { super(); this.account = account; this.depositAmount = depositAmount; } public void run() { for(int i=0;i<100;i++){ account.deposit(depositAmount); } } } |
· 最后咱们测试一下这个取钱和存钱的操做
1 2 3 4 5 6 7 8 9 10 |
public class TestDraw { public static void main(String[] args) { //建立一个帐户 Account account=new Account(); new Thread(new DrawThread(account, 800),"取钱者").start(); new Thread(new depositThread(account, 800),"存款者甲").start(); new Thread(new depositThread(account, 800),"存款者乙").start(); new Thread(new depositThread(account, 800),"存款者丙").start(); } } |
· 大体的输出结果以下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
存款者甲存钱800.0 帐户余额为:800.0 取钱者 取钱:800.0 余额 : 0.0 存款者丙存钱800.0 帐户余额为:800.0 取钱者 取钱:800.0 余额 : 0.0 存款者甲存钱800.0 帐户余额为:800.0 取钱者 取钱:800.0 余额 : 0.0 存款者丙存钱800.0 帐户余额为:800.0 取钱者 取钱:800.0 余额 : 0.0 存款者甲存钱800.0 帐户余额为:800.0 取钱者 取钱:800.0 余额 : 0.0 存款者丙存钱800.0 帐户余额为:800.0 取钱者 取钱:800.0 余额 : 0.0 存款者甲存钱800.0 帐户余额为:800.0 取钱者 取钱:800.0 余额 : 0.0 存款者丙存钱800.0 帐户余额为:800.0 取钱者 取钱:800.0 余额 : 0.0 存款者甲存钱800.0 帐户余额为:800.0 取钱者 取钱:800.0 余额 : 0.0 |
· 如何程序不使用synchronized关键字来保持同步,而是直接适用Lock对像来保持同步,则系统中不存在隐式的同步监视器对象,也就不能使用wait()、notify()、notifyAll()来协调线程的运行.
· 当使用LOCK对象保持同步时,Java为咱们提供了Condition类来协调线程的运行。关于Condition类,JDK文档里进行了详细的解释.,再次就不啰嗦了。
· 咱们就拿Account类进行稍微的修改 一下吧!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Account { //显示定义Lock对象 private final Lock lock=new ReentrantLock(); //得到指定Lock对象对应的条件变量 private final Condition con=lock.newCondition(); private String accountNo; private double balance; //标识帐户中是否有存款的旗标 private boolean flag=false; public Account() { super(); } public Account(String accountNo, double balance) { super(); this.accountNo = accountNo; this.balance = balance; } public void draw (double drawAmount){ //加锁 lock.lock(); try { if(!flag){ // this.wait(); con.await(); }else { //取钱 System.out.println(Thread.currentThread().getName()+" 取钱:"+drawAmount); balance=balance-drawAmount; System.out.println("余额 : "+balance); //将标识帐户是否已有存款的标志设为false flag=false; //唤醒其它线程 // this.notifyAll(); con.signalAll(); } } catch (Exception e) { e.printStackTrace(); } finally{ lock.unlock(); } } public void deposit(double depositAmount){ //加锁 lock.lock(); try { if(flag){ // this.wait(); con.await(); } else{ System.out.println(Thread.currentThread().getName()+"存钱"+depositAmount); balance=balance+depositAmount; System.out.println("帐户余额为:"+balance); flag=true; //唤醒其它线程 // this.notifyAll(); con.signalAll(); } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); }finally{ lock.unlock(); } } } |
· 输出结果和上面是同样的!只不过这里显示的使用Lock对像来充当同步监视器,使用Condition对象来暂停指定线程,唤醒指定线程!
·
管道流是JAVA中线程通信的经常使用方式之一,基本流程以下:
·
1.
建立管道输出流PipedOutputStream pos和管道输入流PipedInputStream pis
2.
3.
将pos和pis匹配,pos.connect(pis);
4.
5.
将pos赋给信息输入线程,pis赋给信息获取线程,就能够实现线程间的通信了
6.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; public class testPipeConnection { public static void main(String[] args) { /** * 建立管道输出流 */ PipedOutputStream pos = new PipedOutputStream(); /** * 建立管道输入流 */ PipedInputStream pis = new PipedInputStream(); try { /** * 将管道输入流与输出流链接 此过程也可经过重载的构造函数来实现 */ pos.connect(pis); } catch (IOException e) { e.printStackTrace(); } /** * 建立生产者线程 */ Producer p = new Producer(pos); /** * 建立消费者线程 */ Consumer1 c1 = new Consumer1(pis); /** * 启动线程 */ p.start(); c1.start(); } } /** * 生产者线程(与一个管道输入流相关联) * */ class Producer extends Thread { private PipedOutputStream pos; public Producer(PipedOutputStream pos) { this.pos = pos; } public void run() { int i = 0; try { while(true) { this.sleep(3000); pos.write(i); i++; } } catch (Exception e) { e.printStackTrace(); } } } /** * 消费者线程(与一个管道输入流相关联) * */ class Consumer1 extends Thread { private PipedInputStream pis; public Consumer1(PipedInputStream pis) { this.pis = pis; } public void run() { try { while(true) { System.out.println("consumer1:"+pis.read()); } } catch (IOException e) { e.printStackTrace(); } } } |
· 程序启动后,就能够看到producer线程往consumer1线程发送数据
consumer1:0
consumer1:1
consumer1:2
consumer1:3
......
·
管道流虽然使用起来方便,可是也有一些缺点
·
o
管道流只能在两个线程之间传递数据 。线程consumer1和consumer2同时从pis中read数据,当线程producer往管道流中写入一段数据后,每个时刻只有一个线程能获取到数据,并非两个线程都能获取到producer发送来的数据,所以一个管道流只能用于两个线程间的通信。不只仅是管道流,其余IO方式都是一对一传输。
o
o
管道流只能实现单向发送,若是要两个线程之间互通信,则须要两个管道流 。能够看到上面的例子中,线程producer经过管道流向线程consumer发送数据,若是线程consumer想给线程producer发送数据,则须要新建另外一个管道流pos1和pis1,将pos1赋给consumer1,将pis1赋给producer,具体例子本文再也不多说。
o
· 管道(Pipe) :管道可用于具备亲缘关系进程间的通讯,容许一个进程和另外一个与它有共同祖先的进程之间进行通讯。
· 命名管道(named pipe) :命名管道克服了管道没有名字的限制,所以,除具备管道所具备的功能外,它还容许无亲缘关系进程间的通讯。命名管道在文件系统中有对应的文件名。命名管道经过命令mkfifo或系统调用mkfifo来建立。
· 信号(Signal) :信号是比较复杂的通讯方式,用于通知接受进程有某种事件发生,除了用于进程间通讯外,进程还能够发送信号给进程自己;Linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又可以统一对外接口,用sigaction函数从新实现了signal函数)。
· 消息(Message)队列 :消息队列是消息的连接表,包括Posix消息队列system V消息队列。有足够权限的进程能够向队列中添加消息,被赋予读权限的进程则能够读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺
· 共享内存 :使得多个进程能够访问同一块内存空间,是最快的可用IPC形式。是针对其余通讯机制运行效率较低而设计的。每每与其它通讯机制,如信号量结合使用,来达到进程间的同步及互斥。
· 内存映射(mapped memory) :内存映射容许任何多个进程间通讯,每个使用该机制的进程经过把一个共享的文件映射到本身的进程地址空间来实现它。
· 信号量(semaphore) :主要做为进程间以及同一进程不一样线程之间的同步手段。
· 套接口(Socket) :更为通常的进程间通讯机制,可用于不一样机器之间的进程间通讯。起初是由Unix系统的BSD分支开发出来的,但如今通常能够移植到其它类Unix系统上:linux和System V的变种都支持套接字。
· 我的介绍
· · springMVC拦截器和过滤器的区别
http://blog.csdn.net/chenleixing/article/details/44573495
· · excel导出功能如何实现
http://blog.csdn.net/gaojinshan/article/details/30221729
· · SpringIOC和AOP,动态代理实现方式
· · 自动装配有哪几种方式,自动装配有什么局限性
模式 |
说明 |
Default |
在每一个bean中都一个autowire=default的默认配置它的含义是: 采用beans和跟标签中的default-autowire="属性值"同样的设置。
|
On |
不使用自动装配,必须经过ref元素指定依赖,默认设置。
|
ByNname |
根据属性名自动装配。此选项将检查容器并根据名字查找与属性彻底一致的bean,并将其与属性自动装配。例如,在bean定义中将autowire设置为by name,而该bean包含master属性(同时提供setMaster(..)方法),Spring就会查找名为master的bean定义,并用它来装配给master属性。 |
Bytype |
若是容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配。若是存在多个该类型的bean,那么将会抛出异常,并指出不能使用byType方式进行自动装配。若没有找到相匹配的bean,则什么事都不发生,属性也不会被设置。若是你不但愿这样,那么能够经过设置dependency-check="objects"让Spring抛出异常。
|
Constructor |
与byType的方式相似,不一样之处在于它应用于构造器参数。若是在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。 |
Antodetect |
经过bean类的自省机制(introspection)来决定是使用constructor仍是byType方式进行自动装配。若是发现默认的构造器,那么将使用byType方式。
|
注意:
byName 和byType
在使用的过程当中必须保证bean可以初始化,不然的话会出现bug
若是有默认的无参数的构造器就不须要多余的配置
若是有带有参数的构造器,那在bean的配置中必须配置器初始化的参数 或者在bean中添加无参数的构造器
基本类型不能够装配,精准度 易混乱bean必须能够得到
· · 数据库引擎,Innodb,MyISAM的区别
1. MySQL默认采用的是MyISAM。
2. MyISAM不支持事务,而InnoDB支持。InnoDB的AUTOCOMMIT默认是打开的,即每条SQL语句会默认被封装成一个事务,自动提交,这样会影响速度,因此最好是把多条SQL语句显示放在begin和commit之间,组成一个事务去提交。
3. InnoDB支持数据行锁定,MyISAM不支持行锁定,只支持锁定整个表。即MyISAM同一个表上的读锁和写锁是互斥的,MyISAM并发读写时若是等待队列中既有读请求又有写请求,默认写请求的优先级高,即便读请求先到,因此MyISAM不适合于有大量查询和修改并存的状况,那样查询进程会长时间阻塞。由于MyISAM是锁表,因此某项读操做比较耗时会使其余写进程饿死。
4. InnoDB支持外键,MyISAM不支持。
5. InnoDB的主键范围更大,最大是MyISAM的2倍。
6. InnoDB不支持全文索引,而MyISAM支持。全文索引是指对char、varchar和text中的每一个词(停用词除外)创建倒排序索引。MyISAM的全文索引其实没啥用,由于它不支持中文分词,必须由使用者分词后加入空格再写到数据表里,并且少于4个汉字的词会和停用词同样被忽略掉。
7. MyISAM支持GIS数据,InnoDB不支持。即MyISAM支持如下空间数据对象:Point,Line,Polygon,Surface等。
8. 没有where的count(*)使用MyISAM要比InnoDB快得多。由于MyISAM内置了一个计数器,count(*)时它直接从计数器中读,而InnoDB必须扫描全表。因此在InnoDB上执行count(*)时通常要伴随where,且where中要包含主键之外的索引列。为何这里特别强调“主键之外”?由于InnoDB中primary index是和raw data存放在一块儿的,而secondary index则是单独存放,而后有个指针指向primary key。因此只是count(*)的话使用secondary index扫描更快,而primary key则主要在扫描索引同时要返回raw data时的做用较大。
· · 索引实现方式,B+树有什么特色,B树和B+数的区别,B+树的实现方式
· · 索引的最左配原则
· · HashMap和HashSet的区别,HashMap是有序的吗
· · LinkedHashMap,保证什么有序,底层实现。
· · java多线程的方式,FutureTask CallAble介绍,CallAble和Runnable的区别
http://www.importnew.com/17572.html
· · 线程池
· · 类的加载过程,双亲委派机制
上午交叉面,下午已回绝。四面挂,心痛。分享面经,为后面校招攒人品。
一面:(8月1号上午:电话面试:80分32秒)
1.自我介绍?
2.作过哪些项目?项目中遇到哪些难点,你是怎样解决的?单点登陆系统说一下?分布式缓存的使用场景?(说好的基础呢,上来就是项目,毫无准备,致使好多东西都记不起来了。面试官还说“那你说一个你记得的项目”,手动无奈。。。)
分布式缓存的典型应用场景可分为如下几类:
1)页面缓存.用来缓存Web页面的内容片断,包括HTML、CSS和图片等,多应用于社交网站等;
2)应用对象缓存.缓存系统做为ORM框架的二级缓存对外提供服务,目的是减轻数据库的负载压力,加速应用访问;
3)状态缓存.缓存包括Session会话状态及应用横向扩展时的状态数据等,这类数据通常是难以恢复的,对可用性要求较高,多应用于高可用集群;
4)并行处理.一般涉及大量中间计算结果须要共享;
5)事件处理.分布式缓存提供了针对事件流的连续查询(continuous query)处理技术,知足实时性需求;
6)极限事务处理.分布式缓存为事务型应用提供高吞吐率、低延时的解决方案,支持高并发事务请求处理,多应用于铁路、金融服务和电信等领域.
3.你实习的时候JDK用的是那个版本,这个版本有什么新的特性?
http://zcc888.gitee.io/2018/03/20/java/#more
Jdk7的新特性:
1.对集合类的语言支持;(??)
2.自动资源管理;
3.改进的通用实例建立类型推断;(??)
4.数字字面量下划线支持;(√)
5.switch中使用string;(√)
JSR292 的实现增长了一个 InvokeDynamic 的字节码指令来支持动态类型语言,使得在把源代码编译成字节码时并不须要肯定方法的签名,即方法参数的类型和返回类型。当运行时执行 InvokeDynamic 指令时,JVM 会经过新的动态连接机制 Method Handles,寻找到真实的方法。
为了防止自定义多线程ClassLoad产生的死锁问题,java.lang.ClassLoader类增长了如下API。
4.G1回收器和其余回收器有什么区别?
并发与并行,部分代 本身就能够,局部复制全局标记整理堆>4G会比较好。
Java 8 update 20所引入的一个很棒的优化就是G1回收器中的字符串去重(String deduplication)。因为字符串(包括它们内部的char[]数组)占用了大多数的堆空间,这项新的优化旨在使得G1回收器能识别出堆中那些重复出现的字符串并将它们指向同一个内部的char[]数组,以免同一个字符串的多份拷贝,那样堆的使用效率会变得很低。你能够使用-XX:+UseStringDeduplication这个JVM参数来试一下这个特性。
Java 8中最大的改变就是持久代的移除,它本来是用来给类元数据,驻留字符串,静态变量来分配空间的。这在之前都是须要开发人员来针对那些会加载大量类的应用来专门进行堆比例的优化及调整。许多年来都是如此,这也正是许多OutOfMemory异常的根源,所以由JVM来接管它真是再好不过了。即使如此,它自己并不会减小开发人员将应用解耦到不一样的JVM中的可能性。
每一个回收器都有许多不一样的开关和选项来进行调优,这可能会增长吞吐量,也可能会减小,这取决于你的应用的具体的行为了。在下一篇文章中咱们会深刻讲解配置这些算法的关键策略。
5.垃圾回收为何会停顿?哪些对象可能做为GCRoots?
虚拟机栈中引用的对象 方法区(静态属性,常量引用的对象)本地方法栈中引用的对象。
6.垃圾回收分代收集算法?为何会有两个Survivor区?new一个对象会保存在哪里?
堆
Survivor的存在乎义,就是减小被送到老年代的对象,进而减小Full GC的发生,Survivor的预筛选保证,只有经历16次Minor GC还能在新生代中存活的对象,才会被送到老年代。
http://blog.csdn.net/antony9118/article/details/51425581
设置两个Survivor区最大的好处就是解决了碎片化
7.Java内存模型?volatile关键字,使用场景?原子性的理解?先行发生原则?
Java内存模型中规定了全部的变量都存储在主内存中,每条线程还有本身的工做内存(能够与前面将的处理器的高速缓存类比),线程的工做内存中保存了该线程使用到的变量到主内存副本拷贝,线程对变量的全部操做(读取、赋值)都必须在工做内存中进行,而不能直接读写主内存中的变量。
· lock(锁定):做用于主内存的变量,把一个变量标识为一条线程独占状态。
· unlock(解锁):做用于主内存变量,把一个处于锁定状态的变量释放出来,释放后的变量才能够被其余线程锁定。
· read(读取):做用于主内存变量,把一个变量值从主内存传输到线程的工做内存中,以便随后的load动做使用
· load(载入):做用于工做内存的变量,它把read操做从主内存中获得的变量值放入工做内存的变量副本中。
· use(使用):做用于工做内存的变量,把工做内存中的一个变量值传递给执行引擎,每当虚拟机遇到一个须要使用变量的值的字节码指令时将会执行这个操做。
· assign(赋值):做用于工做内存的变量,它把一个从执行引擎接收到的值赋值给工做内存的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操做。
· store(存储):做用于工做内存的变量,把工做内存中的一个变量的值传送到主内存中,以便随后的write的操做。
· write(写入):做用于主内存的变量,它把store操做从工做内存中一个变量的值传送到主内存的变量中。
若是要把一个变量从主内存中复制到工做内存,就须要按顺寻地执行read和load操做,若是把变量从工做内存中同步回主内存中,就要按顺序地执行store和write操做。Java内存模型只要求上述操做必须按顺序执行,而没有保证必须是连续执行。也就是read和load之间,store和write之间是能够插入其余指令的,如对主内存中的变量a、b进行访问时,可能的顺序是read a,read b,load b,load a。Java内存模型还规定了在执行上述八种基本操做时,必须知足以下规则:
· 不容许read和load、store和write操做之一单独出现
· 不容许一个线程丢弃它的最近assign的操做,即变量在工做内存中改变了以后必须同步到主内存中。
· 不容许一个线程无缘由地(没有发生过任何assign操做)把数据从工做内存同步回主内存中。
· 一个新的变量只能在主内存中诞生,不容许在工做内存中直接使用一个未被初始化(load或assign)的变量。即就是对一个变量实施use和store操做以前,必须先执行过了assign和load操做。
· 一个变量在同一时刻只容许一条线程对其进行lock操做,lock和unlock必须成对出现
· 若是对一个变量执行lock操做,将会清空工做内存中此变量的值,在执行引擎使用这个变量前须要从新执行load或assign操做初始化变量的值
· 若是一个变量事先没有被lock操做锁定,则不容许对它执行unlock操做;也不容许去unlock一个被其余线程锁定的变量。
· 对一个变量执行unlock操做以前,必须先把此变量同步到主内存中(执行store和write操做)。
Volatile有五个使用场景(参考Brian Goetz (brian.goetz@sun.com)的文章):
1.做为状态标志
2.一次性安全发布
3.独立观察
4.volatile bean模式
5.开销较低的读写锁策略
Java内存模型中存在的自然的先行发生关系:
1. 程序次序规则:同一个线程内,按照代码出现的顺序,前面的代码先行于后面的代码,准确的说是控制流顺序,由于要考虑到分支和循环结构。
2. 管程锁定规则:一个unlock操做先行发生于后面(时间上)对同一个锁的lock操做。
3. volatile变量规则:对一个volatile变量的写操做先行发生于后面(时间上)对这个变量的读操做。
4. 线程启动规则:Thread的start( )方法先行发生于这个线程的每个操做。
5. 线程终止规则:线程的全部操做都先行于此线程的终止检测。能够经过Thread.join( )方法结束、Thread.isAlive( )的返回值等手段检测线程的终止。
6. 线程中断规则:对线程interrupt( )方法的调用先行发生于被中断线程的代码检测到中断事件的发生,能够经过Thread.interrupt( )方法检测线程是否中断
7. 对象终结规则:一个对象的初始化完成先行于发生它的finalize()方法的开始。
8. 传递性:若是操做A先行于操做B,操做B先行于操做C,那么操做A先行于操做C。
8.场景题:如今有三个线程,同时start,用什么方法能够保证线程执行的顺序,线程一执行完线程二执行,线程二执行完线程三执行?
package com.wenjie.threadDemo;
public class JionTest {
public static void main(String[] args) {
final Thread t1 = new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
System.out.println("t1");
}
});
final Thread t2 = new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
try {
t1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("t2");
}
});
final Thread t3 = new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
try {
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("t3");
}
});
t2.start();
t3.start();
t1.start();
}
}
9.你是怎么理解线程安全的?HashMap是线程安全的么?若是多个线程同时修改HashMap时会发生什么状况?
Failfast
死锁
异常concurrentmodeex
10.ConcurrentHashMap底层原理?每一个版本的实现上有什么区别?http://www.cnblogs.com/study-everyday/p/6430462.html#autoid-1-0-0
11.静态代理和动态代理的区别?动态代理是怎么实现的?
12.深拷贝和浅拷贝的区别?http://blog.csdn.net/XIAXIA__/article/details/41652057
13.你作过hadoop的项目,为何要用hadoop?大家处理的文件是什么格式的?写了几个mapper几个reducer?
Hbase,json
14.zookeeper大家用了几台,用来干什么的?通常状况下都是奇数台,那么若是一台挂了,偶数台如何实现master选举?zookeeper的两种启动模式?http://www.cnblogs.com/raphael5200/category/800894.html
15.TCP首部?TCP为何是可靠的?三次握手四次挥手?
TCP提供一种面向链接的、可靠的字节流服务。
面向链接:意味着两个使用TCP的应用(一般是一个客户和一个服务器)在彼此交换数据以前必须先创建一个TCP链接。在一个TCP链接中,仅有两方进行彼此通讯。广播和多播不能用于TCP。
TCP经过下列方式来提供可靠性:
一、应用数据被分割成TCP认为最适合发送的数据块。这和UDP彻底不一样,应用程序产生的数据报长度将保持不变。 (将数据截断为合理的长度)
二、当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。若是不能及时收到一个确认,将重发这个报文段。
(超时重发)
三、当TCP收到发自TCP链接另外一端的数据,它将发送一个确认。这个确认不是当即发送,一般将推迟几分之一秒 。 (对于收到的请求,给出确认响应) (之因此推迟,多是要对包作完整校验)
四、TCP将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程当中的任何变化。若是收到段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段。 (校验出包有错,丢弃报文段,不给出响应,TCP发送数据端,超时时会重发数据)
五、既然TCP报文段做为IP数据报来传输,而IP数据报的到达可能会失序,所以TCP报文段的到达也可能会失序。若是必要,TCP将对收到的数据进行从新排序,将收到的数据以正确的顺序交给应用层。 (对失序数据进行从新排序,而后才交给应用层)
六、既然IP数据报会发生重复,TCP的接收端必须丢弃重复的数据。(对于重复数据,可以丢弃重复数据)
七、TCP还能提供流量控制。TCP链接的每一方都有固定大小的缓冲空间。TCP的接收端只容许另外一端发送接收端缓冲区所能接纳的数据。这将防止较快主机导致较慢主机的缓冲区溢出。(TCP能够进行流量控制,防止较快主机导致较慢主机的缓冲区溢出)TCP使用的流量控制协议是可变大小的滑动窗口协议。
字节流服务::
两个应用程序经过TCP链接交换8bit字节构成的字节流。TCP不在字节流中插入记录标识符。咱们将这称为字节流服务(bytestreamservice)。
TCP对字节流的内容不做任何解释:: TCP对字节流的内容不做任何解释。TCP不知道传输的数据字节流是二进制数据,仍是ASCII字符、EBCDIC字符或者其余类型数据。对字节流的解释由TCP链接双方的应用层解释。
17.你平时喜欢作什么?看过哪些书?最近在看什么书?(这里有个段子,我:最近在看《HTTP权威指南》。面试官:什么?HTTP潜规则?我:???)
柯南 东野圭吾
舞蹈 运动电影
二面:(8月2号晚上:视频面试:47分钟)
1.你那边怎么有点黑啊?(我靠,我也想说啊,暑假寝室集中供电,然而咱们寝室没有电。发面经也不忘吐槽学校,简直坑啊。。。抱着台灯瑟瑟发抖。。。)
2.如今在哪里实习?实习主要作些什么?
3.说一下Java里面你最感兴趣的一个部分?
并发?
4.熟悉Java的哪些框架?用了Spring的哪些东西?Spring如今最新的版本是多少?
5.讲一下MVC设计模式,有什么框架用到了这个模式?spring
6.场景题:一个Controller调用两个Service,这两Service又都分别调用两个Dao,问其中用到了几个数据库链接池的链接?
7.安全方面:如何防止SQL注入?如何防止用户删除其余用户的信息?表单提交能够跨域么?本身写的接口如何防止被其余人恶意调用?
貌似浏览器也不容许js修改已经存在的header,只能增长自定义header: ajax - Set a request header in JavaScript
防止被恶意调用的话,能够作请求限制,第一次请求返回一个随机数,下次请求把随机数带过来,返回时再返回一个随机数
8.zookeeper偶数选举问题?(感受很重视zookeeper啊)
9.hadoop为何要将文件分块而且复制三份,复制两份不行么?这样不浪费空间么?namenode脑裂问题?zookeeper如何管理全局配置文件?大家的Hadoop项目用到了几台机器,每一个机器的做用?
10.Servlet是线程安全的么?
11.建立一个对象的详细过程?其中发生了些什么?
12.Java NIO你了解么?讲一讲你最熟悉的部分?
13.你在生活中有没有遇到什么神奇的事情,能够分享一下么?好比洒水车为何总是在阴天或者快下雨的时候洒水?还有我和我老婆常常吵,阳台的花是早上浇好呢,仍是晚上浇好呢?(我靠,这是什么套路)
14.你认为你身边的同窗怎么样?若是你正在打游戏,你想让同窗帮忙带瓶水,你以为有多少人会帮你带?(这又是什么套路?让我去送水?)
15.你还有什么想问的?
三面:(HR面,8月4号下午:视频面试:22分钟)
1.7岁一个阶段,说一说每个阶段对你影响最大的一我的或事?
2.说一下你大学阶段作了些什么?
3.你感受你前两个面试官怎么样?
4.春招的时候为何没有去bat实习?
5.你当初准备暑期实习的话,是想学到些什么?如今感受本身有哪些进步?
6.你还有什么想问的?(固然是万能的培养计划和晋升机制)
四面:(交叉面,8月16号上午:电话面试:30分钟)
1.自我介绍?
2.说一下最能表明你技术水平的项目吧?
3.maven如何进行依赖管理,如何解决依赖冲突?
http://blog.csdn.net/honghailiang888/article/details/53019635
首先要说明Maven的依赖管理,具体的能够参考这边Maven学习——依赖管理 这篇文章,maven在依赖冲管理中有一下几个原则。
1. 依赖是使用Maven坐标来定位的,而Maven坐标主要由GAV(groupId, artifactId, version)构成。若是两个相同的依赖包,若是groupId, artifactId, version不一样,那么maven也认为这两个是不一样的。
2. 依赖会传递,A依赖了B,B依赖了C,那么A的依赖中就会出现B和C。
3. Maven对同一个groupId, artifactId的冲突仲裁,不是以version越大越保留,而是依赖路径越短越优先,而后进行保留。
4. 依赖的scope会影响依赖的影响范围。
但出现了冲突的时候,好比系统出现了NoSuchMethodError,LinkageError 颇有多是你系统中出现了依赖冲突。出现冲突之后,能够按如下的步骤执行
1.肯定出了问题的jar包名称。一般能够在eclipse中查找冲突的类有在哪些依赖包里面出现了。并肯定实际要使用的是那个包,冲突的包有哪些。
2.经过mvn dependency:tree > tree.txt导出所有的依赖。
3.在导出的依赖文件中,查找问题相关的jar。肯定这些jar是如何被依赖进来的,是直接依赖的仍是经过传递依赖引入的。
4.找到相互冲突的并须要排除的依赖的顶级依赖,并分析冲突的缘由,冲突的缘由多是如下几种:
· 同一个jar包但groupId, artifactId不一样,这种冲突只能经过设定依赖的<exclusions>来进行排除
· 须要的版本jar包依赖路径较长,这种冲突能够把想要版本的依赖直接什么在依赖中,这样路径就最短了优先级最高。
5.最后能够经过打包mvn install来确认打出来的war包中是否有被排除的依赖。
4.maven的源和插件了解哪些?maven的生命周期?
http://blog.csdn.net/limm33/article/details/53142118
5.如何保证分布式缓存的一致性?分布式session实现?
6.spring的bean的建立时机?依赖注入的时机?
7.大家的图片时怎么存储的,对应在数据库中时如何保存图片的信息的?
http://blog.csdn.net/haluoluo211/article/details/52080325最好是二进制或者项目中,直接保存相对路径
8.单点登陆系统的实现?
http://www.cnblogs.com/ywlaker/p/6113927.html
9.项目中用到的JDK的哪些特性?
10.java8流式迭代的好处?
http://www.cnblogs.com/shenlanzhizun/p/6027042.html
11.多线程如何在多个CPU上分布?线程调度算法有哪些?
12.线程调度和进程调度的区别?
13.项目中用到了哪些集合类?
14.说一下TreeMap的实现原理?红黑树的性质?红黑树遍历方式有哪些?若是key冲突如何解决?setColor()方法在何时用?何时会进行旋转和颜色转换?后者覆盖前者 保持惟一性
15.你有什么想问的?
时隔两年,再一次的面临离职找工做,这一次换工做有些许的不舍,也有些许的无奈。我的所在的技术团队不错,两年时间成长了不少,也很不舍这个团队。可是,因为公司的某些缘由和对于自身将来发展的综合考虑,又不得不得离去,去寻找更合适的地方成长和发展。相比于两年前,如今找工做没有那么的着急,也没有那么的迫切,也没有特别想去的公司,反正去大厂互联网公司基本都是加班加点的。也许,这是工做三年的我即将面临的一个坎吧。对于将来的选择和考虑,对于将来的恐惧吧。也许我是杞人忧天,也许是上天注定我将去某一家公司,无论怎样,坚持作最好的本身!不停进步,不停成长!
下面将最近面试遇到的一些题目进行汇总以下,但愿对如今正在找工做的同窗和如今面临毕业找工做的同窗有所帮助。
·
单例模式:懒汉式、饿汉式、双重校验锁、静态加载,内部类加载、枚举类加载。保证一个类仅有一个实例,并提供一个访问它的全局访问点。
·
·
代理模式:动态代理和静态代理,何时使用动态代理。
·
·
适配器模式:将一个类的接口转换成客户但愿的另一个接口。适配器模式使得本来因为接口不兼容而不能一块儿工做的那些类能够一块儿工做。
·
·
装饰者模式:动态给类加功能。
·
·
观察者模式:有时被称做发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知全部观察者对象,使它们可以自动更新本身。
·
·
策略模式:定义一系列的算法,把它们一个个封装起来,而且使它们可相互替换。
·
·
外观模式:为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
·
·
命令模式:将一个请求封装成一个对象,从而使您能够用不一样的请求对客户进行参数化。
·
·
建立者模式:将一个复杂的构建与其表示相分离,使得一样的构建过程能够建立不一样的表示。
·
·
抽象工厂模式:提供一个建立一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
·
·
Java基本类型哪些,所占字节和范围
·
·
Set、List、Map的区别和联系
·
·
何时使用HashMap
·
·
何时使用LinkedHashMap、ConcurrentHashMap、WeakHashMap
·
·
哪些集合类是线程安全的
·
·
为何Set、List、Map不实现Cloneable和Serializable接口
·
·
ConcurrentHashMap的实现,1.7和1.8的实现
·
·
Arrays.sort的实现
·
·
何时使用CopyOnArrayList
·
·
volatile的使用
·
·
Synchronied的使用
·
·
ReentrantLock的实现以及和Synchronied的区别
·
·
CAS的实现原理以及问题
·
·
AQS的实现原理
·
·
接口和抽象类的区别,何时使用
·
·
类加载机制的步骤,每一步作了什么,static和final修改的成员变量的加载时机
·
·
双亲委派模型
·
·
反射机制:反射动态擦除泛型、反射动态调用方法等
·
·
动态绑定:父类引用指向子类对象
·
·
JVM内存管理机制:有哪些区域,每一个区域作了什么
·
·
JVM垃圾回收机制:垃圾回收算法 垃圾回收器 垃圾回收策略
·
·
jvm参数的设置和jvm调优
·
·
什么状况产生年轻代内存溢出、什么状况产生年老代内存溢出
·
·
内部类:静态内部类和匿名内部类的使用和区别
·
·
redis和memcached:何时选择redis,何时选择memcached,内存模型和存储策略是什么样的
·
·
·
·
mysql的优化策略有哪些
·
·
mysql索引的实现B+树的实现原理
·
·
什么状况索引不会命中,会形成全表扫描
·
·
java中bio nio aio的区别和联系
·
·
为何bio是阻塞的nio是非阻塞的nio的模型是什么样的
·
·
java io的总体架构和使用的设计模式
·
·
Reactor模型和Proactor模型
·
·
http请求报文结构和内容
·
·
http三次握手和四次挥手
·
·
rpc相关:如何设计一个rpc框架,从io模型 传输协议 序列化方式综合考虑
·
·
linux命令 统计,排序,前几问题等
·
·
StringBuff和StringBuilder的实现,底层实现是经过byte数据,外加数组的拷贝来实现的
·
·
cas操做的使用
·
·
内存缓存和数据库的一致性同步实现
·
·
微服务的优缺点
·
·
线程池的参数问题
·
·
ip问题 如何判断ip是否在多个ip段中
·
·
判断数组两个中任意两个数之和是否为给定的值
·
·
乐观锁和悲观锁的实现
·
·
synchronized实现原理
·
·
你在项目中遇到的困难和怎么解决的
·
·
你在项目中完成的比较出色的亮点
·
·
消息队列广播模式和发布/订阅模式的区别
·
·
生产者消费者代码实现
·
·
死锁代码实现
·
·
线程池:参数,每一个参数的做用,几种不一样线程池的比较,阻塞队列的使用,拒绝策略
·
·
Future和ListenableFuture异步回调相关
·
·
算法相关:判断可否从数组中找出两个数字和为给定值,随机生成1~10000不重复并放入数组,求数组的子数组的最大和,二分查找算法的实现及其时间复杂计算
·
·
算法:经常使用排序算法,二分查找,链表相关,数组相关,字符串相关,树相关等
·
·
常见序列化协议及其优缺点
·
·
memcached内存原理,为何是基于块的存储
·
·
搭建一个rpc须要准备什么
·
·
若是线上服务器频繁地出现full gc,如何去排查
·
·
若是某一时刻线上机器忽然量变得很大,服务扛不住了,怎么解决
·
·
LRU算法的实现
·
·
LinkedHashMap实现LRU
·
·
定义栈的数据结构,请在该类型中实现一个可以找到栈最小元素的min函数
·
·
海量数据处理的解决思路
·
·
reactor模型的演变
·
·
阻塞、非阻塞、同步、异步区别
·
·
Collection的子接口
·
·
jvm调优相关
·
·
zookeeper相关,节点类型,如何实现服务发现和服务注册
·
·
nginx负载均衡相关,让你去实现负载均衡,该怎么实现
·
·
linux命令,awk、cat、sort、cut、grep、uniq、wc、top等
·
·
压力测试相关,怎么分析,单接口压测和多状况下的压测
·
·
你以为你的优势是什么,你的缺点是什么,为何咱们要录用你
·
·
Spring mvc的实现原理
·
·
netty底层实现,IO模型,ChannelPipeline的实现和原理
·
·
缓存的设计和优化
·
·
缓存和数据库一致性同步解决方案
·
·
你所在项目的系统架构,谈谈总体实现
·
·
消息队列的使用场景
·
·
ActiveMQ、RabbitMQ、Kafka的区别
·
·
JVM内存分配策略和垃圾回收时机
·
·
JVM垃圾回收策略和对象的实际生命周期
·
·
对象是如何在堆中分配的
·
·
full gc触发的场景,线上若是一直full gc怎么排查
·
·
如何防止接口被恶意攻击
·
·
线上某一台服务器出现问题,如何实际操做去解决
·
·
线上接口最大的QPS以及如何评估服务器可承受的最大请求数
·
·
内存缓存的使用场景和优缺点
·
·
怎么防止线上接口被恶意刷
·
·
怎么防止线上接口被攻击
·
·
栈帧的结构
·
·
transient关键字的使用
·
以上内容为近期的面试总结。后续若有新的内容,会持续更新。
hashMap能够key为空或者value为空吗?能够同时为空吗?
HashSet有什么特色?
话题二:
HashMap底层是怎么实现的?
1.6:数组+链表
1.8:数组+链表/红黑树
为何要二次hash?谈谈扩容|何时扩容?
HashMap与Hashtable有什么区别吗?
Hashtable加同步锁有什么问题?能不能有更好的实现方式?
ConcurrentHashMap底层怎么实现的?怎么保证同步的(CAS)?
话题三:
若是前面的,你都答出来了?
什么是CAS?它synchronized有什么区别?
谈谈synchronized?
能谈一下volatile吗?
六、JVM连环炮+并发编程?
话题一:
一、谈谈内存区域?
堆、栈、方法区、(程序计算器、本地方法栈 )|能够不谈
二、堆、栈、方法区分别有什么用?存储什么内容?
三、能谈谈堆吗?
新生代、老年代
四、怎么判断对象不可用?
五、能谈一下GC策略吗?它是怎么回收不可用对象的?
标记-清除,复制、标记-整理、分代。
六、能谈一下垃圾回收器吗?(暂无遇见问的)
七、对象怎么分配的?
话题二:
一、谈一下类加载过程?
二、谈一下双亲委派机制?
话题三:
一、谈一下Java内存模型
二、谈一下Synchronized、volatile?
二、谈一下AQS、CountDownLatch、ReentrantLock?(暂时尚未人问)
三、谈一下ThreadLocal?
四、谈一下CAS?
五、谈一下线程池原理?
2、设计模式
一、谈一下六种设计原则?开闭原则什么意思?里氏XX是什么意思?
二、写一个单例模式?后续本身扩展各类的优缺点?
三、谈一个你熟悉的设计模式?
3、缓存
一、设计一个高效的缓存?
http://www.cnblogs.com/xiaopohou/archive/2011/08/31/2160437.html
二、谈谈LRU算法?(解决高效的缓存)
3、架构思想、高并发、大数据量解决方案。
一、一个很大的日记文件,统计出访问排行?
二、mapreduce思想?谈谈shuffle?
一、unordered_map的实现原理。。很具体的描述
二、单链表多路归并排序
三、LRU cache的实现,插入、查找、删除时间复杂度不能超过O(1)
有一个场景,如今cache满了,须要淘汰频率最低的那个
更新:0824华为
关于HTTP请求GET和POST的区别
1.GET提交,请求的数据会附在URL以后(就是把数据放置在HTTP协议头<request-line>中),以?分割URL和传输数据,多个参数用&链接;例如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0 %E5%A5%BD。若是数据是英文字母/数字,原样发送,若是是空格,转换为+,若是是中文/其余字符,则直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII。
POST提交:把提交的数据放置在是HTTP包的包体<request-body>中。上文示例中红色字体标明的就是实际的传输数据
所以,GET提交的数据会在地址栏中显示出来,而POST提交,地址栏不会改变
2.传输数据的大小:
首先声明,HTTP协议没有对传输的数据大小进行限制,HTTP协议规范也没有对URL长度进行限制。而在实际开发中存在的限制主要有:
GET:特定浏览器和服务器对URL长度有限制,例如IE对URL长度的限制是2083字节(2K+35)。对于其余浏览器,如Netscape、FireFox等,理论上没有长度限制,其限制取决于操做系统的支持。
所以对于GET提交时,传输数据就会受到URL长度的限制。
POST:因为不是经过URL传值,理论上数据不受限。但实际各个WEB服务器会规定对post提交数据大小进行限制,Apache、IIS6都有各自的配置。
3.安全性:
POST的安全性要比GET的安全性高。注意:这里所说的安全性和上面GET提到的“安全”不是同个概念。上面“安全”的含义仅仅是不做数据修改,而这里安全的含义是真正的Security的含义,好比:经过GET提交数据,用户名和密码将明文出如今URL上,由于(1)登陆页面有可能被浏览器缓存,(2)其余人查看浏览器的历史纪录,那么别人就能够拿到你的帐号和密码了,
Http协议:一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据4个部分组成,下图给出了请求报文的通常格式。
请求行由请求方法字段、URL字段和HTTP协议版本字段3个字段组成,它们用空格分隔。例如,GET /index.html HTTP/1.1。
请求头部由关键字/值对组成,每行一对,关键字和值用英文冒号“:”分隔。请求头部通知服务器有关于客户端请求的信息,典型的请求头有:
User-Agent:产生请求的浏览器类型。
Accept:客户端可识别的内容类型列表。
Host:请求的主机名,容许多个域名同处一个IP地址,即虚拟主机。
HTTP响应也由三个部分组成,分别是:状态行、消息报头、响应正文。
HTTP:是互联网上应用最为普遍的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它能够使浏览器更加高效,使网络传输减小。
HTTPS:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,所以加密的详细内容就须要SSL。
HTTPS协议的主要做用能够分为两种:一种是创建一个信息安全通道,来保证数据传输的安全;另外一种就是确认网站的真实性。
HTTPS和HTTP的区别主要以下:
一、https协议须要到ca申请证书,通常免费证书较少,于是须要必定费用。
二、http是超文本传输协议,信息是明文传输,https则是具备安全性的ssl加密传输协议。
三、http和https使用的是彻底不一样的链接方式,用的端口也不同,前者是80,后者是443。
四、http的链接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
对称密码加解密,非对称密码加解密。
事务隔离级别和实现方式。
遇到问题:分布式加锁问题:
memcached分布式锁:一、实现原理:
memcached带有add函数,利用add函数的特性便可实现分布式锁。add和set的区别在于:若是多线程并发set,则每一个set都会成功,但最后存储的值以最后的set的线程为准。而add的话则相反,add会添加第一个到达的值,并返回true,后续的添加则都会返回false。利用该点便可很轻松地实现分布式锁。
二、优势
并发高效。
三、缺点
效率对库依赖比较重,重量级
(1)memcached采用列入LRU置换策略,因此若是内存不够,可能致使缓存中的锁信息丢失。
(2)memcached没法持久化,一旦重启,将致使信息丢失。
Redis:redis分布式锁便可以结合zk分布式锁锁高度安全和memcached并发场景下效率很好的优势,能够利用jedis客户端实现。
URL到页面相应的全过程:
浏览器缓存etc缓存 路由缓存 服务提供商缓存 递归到根dns,请求链接TCP。发送报文,恢复
Spring AOP开发用到了那些部分?
==通常只用到了基本数据类型比较
一、equals方法用于比较对象的内容是否相等(覆盖之后)
二、hashcode方法只有在集合中用到
三、当覆盖了equals方法时,比较对象是否相等将经过覆盖后的equals方法进行比较(判断对象的内容是否相等)。
四、将对象放入到集合中时,首先判断要放入对象的hashcode值与集合中的任意一个元素的hashcode值是否相等,若是不相等直接将该对象放入集合中。若是hashcode值相等,而后再经过equals方法判断要放入对象与集合中的任意一个对象是否相等,若是equals判断不相等,直接将该元素放入到集合中,不然不放入。
做者:Xoper.ducky
连接:https://www.nowcoder.com/discuss/3043
来源:牛客网
J2SE基础
1. 九种基本数据类型的大小,以及他们的封装类。
基本类型 |
大小(字节) |
默认值 |
封装类 |
byte |
1 |
(byte)0 |
Byte |
short |
2 |
(short)0 |
Short |
int |
4 |
0 |
Integer |
long |
8 |
0L |
Long |
float |
4 |
0.0f |
Float |
double |
8 |
0.0d |
Double |
boolean |
- |
false |
Boolean |
char |
2 |
\u0000(null) |
Character |
void |
- |
- |
Void |
2. Switch可否用string作参数?
3. equals与==的区别。
4. Object有哪些公用方法?
Wait notify notifyall clone equels getclass
5. Java的四种引用,强弱软虚,用到的场景。
6. Hashcode的做用。
7. ArrayList、LinkedList、Vector的区别。
8. String、StringBuffer与StringBuilder的区别。
9. Map、Set、List、Queue、Stack的特色与用法。
10. HashMap和HashTable的区别。
11. HashMap和ConcurrentHashMap的区别,HashMap的底层源码。
12. TreeMap、HashMap、LindedHashMap的区别。
13. Collection包结构,与Collections的区别。
14. try catch finally,try里有return,finally还执行么?
15. Excption与Error包结构。OOM你遇到过哪些状况,SOF你遇到过哪些状况。
16. Java面向对象的三个特征与含义。
17. Override和Overload的含义去区别。
18. Interface与abstract类的区别。
19. Static class 与non static class的区别。
20. java多态的实现原理。
同一操做不一样结果,前期绑定后期绑定
21.实现多线程的两种方法:Thread与Runable。Call
22.线程同步的方法:sychronized、lock、reentrantLock等。
23.锁的等级:方法锁、对象锁、类锁。
24.写出生产者消费者模式。
25. ThreadLocal的设计理念与做用。Thread ThreadLocal->ThreadLocalMap
26. ThreadPool用法与优点。
27. Concurrent包里的其余东西:ArrayBlockingQueue、CountDownLatch等等。
28. wait()和sleep()的区别。
29. foreach与正常for循环效率对比。
30. Java IO与NIO。
31.反射的做用于原理。
32.泛型经常使用特色,List<String>可否转为List<Object>。
33.解析XML的几种方式的原理与特色:DOM、SAX、PULL。
34. Java与C++对比。
35. Java1.7与1.8新特性。
36.设计模式:单例、工厂、适配器、责任链、观察者等等。
37. JNI的使用。
Java里有不少很杂的东西,有时候须要你阅读源码,大多数可能书里面讲的不是太清楚,须要你在网上寻找答案。
推荐书籍:《java核心技术卷I》《Thinking in java》《java并发编程》《effictive java》《大话设计模式》
JVM
1.内存模型以及分区,须要详细到每一个区放什么。
2.堆里面的分区:Eden,survival from to,老年代,各自的特色。
3.对象建立方法,对象的内存分配,对象的访问定位。
4. GC的两种断定方法:引用计数与引用链。
5. GC的三种收集方法:标记清除、标记整理、复制算法的原理与特色,分别用在什么地方,若是让你优化收集方法,有什么思路?
6. GC收集器有哪些?CMS收集器与G1收集器的特色。
7. Minor GC与Full GC分别在何时发生?
8.几种经常使用的内存调试工具:jmap、jstack、jconsole。
9.类加载的五个过程:加载、验证、准备、解析、初始化。
10.双亲委派模型:Bootstrap ClassLoader、Extension ClassLoader、ApplicationClassLoader。
11.分派:静态分派与动态分派。
JVM过去过来就问了这么些问题,没怎么变,内存模型和GC算法这块问得比较多,能够在网上多找几篇博客来看看。
推荐书籍:《深刻理解java虚拟机》
操做系统
1.进程和线程的区别。
2.死锁的必要条件,怎么处理死锁。
3. Window内存管理方式:段存储,页存储,段页存储。
4.进程的几种状态。
5. IPC几种通讯方式。
6.什么是虚拟内存。
7.虚拟地址、逻辑地址、线性地址、物理地址的区别。
由于是作android的这一块问得比较少一点,还有可能上我简历上没有写操做系统的缘由。
推荐书籍:《深刻理解现代操做系统》
TCP/IP
1. OSI与TCP/IP各层的结构与功能,都有哪些协议。
2. TCP与UDP的区别。
3. TCP报文结构。
4. TCP的三次握手与四次挥手过程,各个状态名称与含义,TIMEWAIT的做用。
5. TCP拥塞控制。
6. TCP滑动窗口与回退N针协议。
7. Http的报文结构。
8. Http的状态码含义。
9. Http request的几种类型。
10. Http1.1和Http1.0的区别
11. Http怎么处理长链接。
12. Cookie与Session的做用于原理。
13.电脑上访问一个网页,整个过程是怎么样的:DNS、HTTP、TCP、OSPF、IP、ARP。
14. Ping的整个过程。ICMP报文是什么。
15. C/S模式下使用socket通讯,几个关键函数。
16. IP地址分类。
17.路由器与交换机区别。
网络其实大致分为两块,一个TCP协议,一个HTTP协议,只要把这两块以及相关协议搞清楚,通常问题不大。
推荐书籍:《TCP/IP协议族》
数据结构与算法
1.链表与数组。
2.队列和栈,出栈与入栈。
3.链表的删除、插入、反向。
4.字符串操做。
5. Hash表的hash函数,冲突解决方法有哪些。
6.各类排序:冒泡、选择、插入、希尔、归并、快排、堆排、桶排、基数的原理、平均时间复杂度、最坏时间复杂度、空间复杂度、是否稳定。
7.快排的partition函数与归并的Merge函数。
8.对冒泡与快排的改进。
9.二分查找,与变种二分查找。
10.二叉树、B+树、AVL树、红黑树、哈夫曼树。
11.二叉树的前中后续遍历:递归与非递归写法,层序遍历算法。
12.图的BFS与DFS算法,最小生成树prim算法与最短路径Dijkstra算法。
13. KMP算法。
14.排列组合问题。
15.动态规划、贪心算法、分治算法。(通常不会问到)
16.大数据处理:相似10亿条数据找出最大的1000个数.........等等
算法的话实际上是个重点,由于最后都是要你写代码,因此算法仍是须要花很多时间准备,这里有太多算法题,写不全,个人建议是没事多在OJ上刷刷题(牛客网、leetcode等),剑指offer上的算法要能理解并本身写出来,编程之美也推荐看一看。
推荐书籍:《大话数据结构》《剑指offer》《编程之美》
如下是我常问的几个问题,若是须要能够参考:
1.贵公司一贯以XXX著称,能不能说明一下公司这方面的特色?
2.贵公司XXX业务发展很好,这是公司发展的重点么?
3.对技术和业务怎么看?
4.贵公司通常的团队是多大,几我的负责一个产品或者业务?
5.贵公司的开发中是否会使用到一些最新技术?
6.对新人有没有什么培训,会不会安排导师?
7.对Full Stack怎么看?
8.你以为我有哪些须要提升的地方?
网易小袁兵总结:
1 java concurrent包下有哪些类,了解哪些锁
2 hashmap和concurrenthashmap有什么区别?各自的机制是什么样的?hashmap如何解决链表过长?红黑树有哪些特性?
· * 每一个结点要么是“红色”,要么是“黑色”(后面将说明)
· * 全部的叶结点都是空结点,而且是“黑色”的
· * 若是一个结点是“红色”的,那么它的两个子结点都是“黑色”的
· * (注:也就是說,若是結點是黑色的,那么它的子節點能够是紅色或者是黑色的)。
· * 结点到其子孙结点的每条简单路径都包含相同数目的“黑色”结点
· * 根结点永远是“黑色”的
红黑树可以以O(log2 n)的时间复杂度进行搜索、插入、删除操做。此外,因为它的设计,任何不平衡都会在三次旋转以内解决。
· 之因此称为红黑树的缘由就在于它的每一个结点都被“着色”为红色或黑色。这些结点颜色被用来检测树的平衡性。但须要注意的是,红黑树并非平衡二叉树,偏偏相反,红黑树放松了平衡二叉树的某些要求,因为必定限度的“不平衡”,红黑树的性能获得了提高。
·
· 从根结点到叶结点的黑色结点数被称为树的“黑色高度”(black-height)。前面关于红黑树的性质保证了从根结点到叶结点的路径长度不会超过任何其余路径的两倍。
对于给定的黑色高度为n的红黑树,从根到叶结点的简单路径的最短长度为n-1,最大长度为2(n-1)。
3 怎么样实现公平锁?实现机制?
同步队列啊有头信息得到锁以前看是否有前驱节点没有得到锁。
4 java引用类型有哪些?各有什么特色?
就能够他的名字同样,任什么时候候GC是不能回收他的,哪怕内存不足时,系统会直接抛出异常OutOfMemoryError,也不会去回收,首先要说明的是java中默认就是强引用,
软引用他的特色是当内存足够时不会回收这种引用类型的对象,只有当内存不够用时才会回收,这种特色很适合最一些缓存。
SoftReference<Person> personSoftReference = new SoftReference<>(jack);
虚引用的特色是只要GC一运行就会把给回收了,我的感受没多大用处,由于只要GC一运行他就会被回收了。
WeakReference<Person> personSoftReference = new WeakReference<Person>(jack);
5 遇过哪些内存泄漏的问题?什么缘由?
指因为疏忽或错误形成程序未能释放已经再也不使用的内存的状况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,于是形成了内存的浪费。就算数据失效了,可是就是不能够gc.
内存泄露是指无用对象(再也不使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而形成的内存空间的浪费称为内存泄露。
一、静态集合类引发内存泄露:
像HashMap、Vector等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,他们所引用的全部的对象Object也不能被释放,由于他们也将一直被Vector等引用着。
例:
Static Vector v = new Vector(10);
for (int i = 1; i<100; i++)
{
Object o = new Object();
v.add(o);
o = null;
}//
在这个例子中,循环申请Object对象,并将所申请的对象放入一个Vector中,若是仅仅释放引用自己(o=null),那么Vector仍然引用该对象,因此这个对象对GC来讲是不可回收的。所以,若是对象加入到Vector后,还必须从Vector中删除,最简单的方法就是将Vector对象设置为null。
二、当集合里面的对象属性被修改后,再调用remove()方法时不起做用。
例:
public static void main(String[] args)
{
Set<Person> set = new HashSet<Person>();
Person p1 = new Person("唐僧","pwd1",25);
Person p2 = new Person("孙悟空","pwd2",26);
Person p3 = new Person("猪八戒","pwd3",27);
set.add(p1);
set.add(p2);
set.add(p3);
System.out.println("总共有:"+set.size()+" 个元素!"); //结果:总共有:3 个元素!
p3.setAge(2); //修改p3的年龄,此时p3元素对应的hashcode值发生改变
set.remove(p3); //此时remove不掉,形成内存泄漏
set.add(p3); //从新添加,竟然添加成功
System.out.println("总共有:"+set.size()+"个元素!"); //结果:总共有:4个元素!
for (Person person : set)
{
System.out.println(person);
}
}
三、监听器
在java编程中,咱们都须要和监听器打交道,一般一个应用当中会用到不少监听器,咱们会调用一个控件的诸如addXXXListener()等方法来增长监听器,但每每在释放对象的时候却没有记住去删除这些监听器,从而增长了内存泄漏的机会。
四、各类链接
好比数据库链接(dataSourse.getConnection()),网络链接(socket)和io链接,除非其显式的调用了其close()方法将其链接关闭,不然是不会自动被GC回收的。对于Resultset和Statement对象能够不进行显式回收,但Connection必定要显式回收,由于Connection在任什么时候候都没法自动回收,而Connection一旦回收,Resultset和Statement对象就会当即为NULL。可是若是使用链接池,状况就不同了,除了要显式地关闭链接,还必须显式地关闭Resultset Statement对象(关闭其中一个,另一个也会关闭),不然就会形成大量的Statement对象没法释放,从而引发内存泄漏。这种状况下通常都会在try里面去的链接,在finally里面释放链接。
五、内部类和外部模块等的引用
内部类的引用是比较容易遗忘的一种,并且一旦没释放可能致使一系列的后继类对象没有释放。此外程序员还要当心外部模块不经意的引用,例如程序员A负责A模块,调用了B模块的一个方法如:
public void registerMsg(Object b);
这种调用就要很是当心了,传入了一个对象,极可能模块B就保持了对该对象的引用,这时候就须要注意模块B是否提供相应的操做去除引用。
六、单例模式
不正确使用单例模式是引发内存泄露的一个常见问题,单例对象在被初始化后将在JVM的整个生命周期中存在(以静态变量的方式),若是单例对象持有外部对象的引用,那么这个外部对象将不能被jvm正常回收,致使内存泄露,考虑下面的例子:
class A{
public A(){
B.getInstance().setA(this);
}
....
}
//B类采用单例模式
class B{
private A a;
private static B instance=new B();
public B(){}
public static B getInstance(){
return instance;
}
public void setA(A a){
this.a=a;
}
//getter...
}
显然B采用singleton模式,它持有一个A对象的引用,而这个A类的对象将不能被回收。想象下若是A是个比较复杂的对象或者集合类型会发生什么状况
6 怎么样实现list的线程安全?
Copyandwritearraylist concurrent...Vector
7 怎么样实现一个缓存中的LRU算法?
yes
8 listhashmap的原理
2016/03/22 |分类:基础技术 | 0条评论 |标签:LinkedHashMap
分享到:11
原文出处:Yikun
在理解了#7介绍的HashMap后,咱们来学习LinkedHashMap的工做原理及实现。首先仍是相似的,咱们写一个简单的LinkedHashMap的程序:
1 2 3 4 5 6 7 8 9 10 11 12 |
LinkedHashMap<String, Integer> lmap = new LinkedHashMap<String, Integer>(); lmap.put("语文", 1); lmap.put("数学", 2); lmap.put("英语", 3); lmap.put("历史", 4); lmap.put("政治", 5); lmap.put("地理", 6); lmap.put("生物", 7); lmap.put("化学", 8); for(Entry<String, Integer> entry : lmap.entrySet()) { System.out.println(entry.getKey() + ": " + entry.getValue()); } |
运行结果是:
1 2 3 4 5 6 7 8 |
语文: 1 数学: 2 英语: 3 历史: 4 政治: 5 地理: 6 生物: 7 化学: 8 |
咱们能够观察到,和HashMap的运行结果不一样,LinkedHashMap的迭代输出的结果保持了插入顺序。是什么样的结构使得LinkedHashMap具备如此特性呢?咱们仍是同样的看看LinkedHashMap的内部结构,对它有一个感性的认识:
没错,正如官方文档所说:
Hash table and linked list implementation of the Map interface, with predictable iteration order. This implementation differs from HashMap in that it maintains a doubly-linked listrunning through all of its entries. This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order).
LinkedHashMap是Hash表和链表的实现,而且依靠着双向链表保证了迭代顺序是插入的顺序。
在HashMap中提到了下面的定义:
1 2 3 4 |
// Callbacks to allow LinkedHashMap post-actions void afterNodeAccess(Node<K,V> p) { } void afterNodeInsertion(boolean evict) { } void afterNodeRemoval(Node<K,V> p) { } |
LinkedHashMap继承于HashMap,所以也从新实现了这3个函数,顾名思义这三个函数的做用分别是:节点访问后、节点插入后、节点移除后作一些事情。
afterNodeAccess函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
void afterNodeAccess(Node<K,V> e) { // move node to last LinkedHashMap.Entry<K,V> last; // 若是定义了accessOrder,那么就保证最近访问节点放到最后 if (accessOrder && (last = tail) != e) { LinkedHashMap.Entry<K,V> p = (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after; p.after = null; if (b == null) head = a; else b.after = a; if (a != null) a.before = b; else last = b; if (last == null) head = p; else { p.before = last; last.after = p; } tail = p; ++modCount; } } |
就是说在进行put以后就算是对节点的访问了,那么这个时候就会更新链表,把最近访问的放到最后,保证链表。
afterNodeInsertion函数
1 2 3 4 5 6 7 8 |
void afterNodeInsertion(boolean evict) { // possibly remove eldest LinkedHashMap.Entry<K,V> first; // 若是定义了移除规则,则执行相应的溢出 if (evict && (first = head) != null && removeEldestEntry(first)) { K key = first.key; removeNode(hash(key), key, null, false, true); } } |
若是用户定义了removeEldestEntry的规则,那么即可以执行相应的移除操做。
afterNodeRemoval函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
void afterNodeRemoval(Node<K,V> e) { // unlink // 从链表中移除节点 LinkedHashMap.Entry<K,V> p = (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after; p.before = p.after = null; if (b == null) head = a; else b.after = a; if (a == null) tail = b; else a.before = b; } |
这个函数是在移除节点后调用的,就是将节点从双向链表中删除。
咱们从上面3个函数看出来,基本上都是为了保证双向链表中的节点次序或者双向链表容量所作的一些额外的事情,目的就是保持双向链表中节点的顺序要从eldest到youngest。
9 手写一个算法,随便一个整数num,一个表明进制的整数k(小于10),实现num的k进制转换
10 实现一个算法,数据库有一个按顺序排列的歌单,用户在前台修改了顺序,现要把数据库的歌单修改为一样的顺序,问怎么样操做最少.
11 实现一个算法,一个文档有若干单词(内存放不下),现要求出10个频度最高的单词
12 jvm中适合高吞吐量的垃圾回收器
http://blog.csdn.net/lghuntfor/article/details/51052737
(1)特色:
–同ParNew回收器同样, 不一样的地方在于,它很是关注系统的吞吐量(经过参数控制)
–使用复制算法
–支持自适应的GC调节策略
-XX:+UseParallelGC新生代用ParallelGC回收器, 老年代使用串行回收器
-XX:+UseParallelOldGC新生代用ParallelGC回收器, 老年代使用ParallelOldGC回收器系统吞吐量的控制:
-XX:MaxGCPauseMillis=n(单位ms) 设置垃圾回收的最大停顿时间,
-XX:GCTimeRatio=n(n在0-100之间) 设置吞吐量的大小, 假设值为n, 那系统将花费不超过1/(n+1)的时间用于垃圾回收
-XX:+UseAdaptiveSizePolicy打开自适应GC策略, 在这种模式下, 新生代的大小, eden,survivior的比例, 晋升老年代的对象年龄等参数会被自动调整,以达到堆大小, 吞吐量, 停顿时间之间的平衡点
13 cms垃圾回收器的特色
14 有几种垃圾回收算法
15 计算机网络osi模型
16 tcp如何实现拥塞控制和流量控制?具体算法是什么?
http://blog.csdn.net/honour2sword/article/details/45191115
http://blog.csdn.net/yechaodechuntian/article/details/25429143
17 http头部格式
HTTP请求消息头部实例:
Host:rss.sina.com.cn
User-Agent:Mozilla/五、0 (Windows; U; Windows NT 五、1; zh-CN; rv:一、八、一、14) Gecko/20080404 Firefox/二、0、0、14
Accept:text/xml,application/xml,application/xhtml+xml,text/html;q=0、9,text/plain;q=0、8,image/png,*/*;q=0、5
Accept-Language:zh-cn,zh;q=0、5
Accept-Encoding:gzip,deflate
Accept-Charset:gb2312,utf-8;q=0、7,*;q=0、7
Keep-Alive:300
Connection:keep-alive
Cookie:userId=C5bYpXrimdmsiQmsBPnE1Vn8ZQmdWSm3WRlEB3vRwTnRtW <-- Cookie
If-Modified-Since:Sun, 01 Jun 2008 12:05:30 GMT
Cache-Control:max-age=0
HTTP响应消息头部实例:
Status:OK - 200 <--响应状态码,表示web服务器处理的结果。
Date:Sun, 01 Jun 2008 12:35:47 GMT
Server:Apache/二、0、61 (Unix)
Last-Modified:Sun, 01 Jun 2008 12:35:30 GMT
Accept-Ranges:bytes
Content-Length:18616
Cache-Control:max-age=120
Expires:Sun, 01 Jun 2008 12:37:47 GMT
Content-Type:application/xml
Age:2
X-Cache:HIT from 236-4一、D0707195一、sina、com、cn <--反向代理服务器使用的HTTP头部
Via:1.0 236-41.D07071951.sina.com.cn:80 (squid/2.6.STABLE13)
Connection:close
18 实现一个用户登陆功能,在不使用https的状况下完成安全传输
19 有哪些非对称加密算法
RSA, EI Gamal, ECC, Knapsack, etc.
RSA是企业级应用标准,不少第三方的加密软件使用RSA 2048bit加密。
ECC更高效,164bitECC约等于1024bit的RSA,常用在移动设备上。
20 linux了解吗?
21 class字节码文件格式是什么?
ClassFile中的字段简单说明以下:
一、MagicNumber:MagicNumber是用来标志class文件的,虚拟机加载class文件的时候会先检查这四个字节,若是不是cafe babe则虚拟机拒绝加载该文件,这样就能够防止加载非class文件而浪费系统资源。这个字段的长度是4个字节,值是固定的cafebabe。
二、Version:version字段有2个长度都为2字节的字段组成,分别是Major Version和Minor Version,分别表明当前class文件的主版本号和次版本号。随着Java技术的不断发展,Java class文件格式会增长一些新的内容来支持Java语言的新特性。同时,不一样的虚拟机支持的Java class文件的版本范围是不一样的,因此在加载class文件以前能够先看看该class文件是否在当前虚拟机的支持范围以内,避免加载不支持的class文件。
三、常量池
首先是2个字节的长度字段constant_pool_count,代表常量池包含了多少个常量。
后面跟着就是constant_pool_count个常量,常量池里放的是字面常量和符号引用。
字面常量主要包含文本串以及被声明为final的常量等;符号引用包含类和接口的全局限定名,字段的名称和描述符,方法的名称和描述符,由于java语言在编译的时候没有链接这一步,全部的引用都是运行时动态加载的,因此就须要把这些引用的信息保存在class文件里。
这里的常量又根据具体的类型分红字符串,整形,长整型,浮点型,双精度浮点型这几种基本类型。
而符号引用保存的是对应的引用的全局限定名,因此保存的是字符串。
四、access_flag 保存了当前类的访问权限
五、this_cass 保存了当前类的全局限定名在常量池里的索引
六、super class 保存了当前类的父类的全局限定名在常量池里的索引
七、interfaces 保存了当前类实现的接口列表,包含两部份内容:interfaces_count 和interfaces[interfaces_count]
interfaces_count 指的是当前类实现的接口数目
interfaces[] 是包含interfaces_count个接口的全局限定名的索引的数组
八、fields 保存了当前类的成员列表,包含两部分的内容:fields_count 和 fields[fields_count]
fields_count是类变量和实例变量的字段的数量总和。
fileds[]是包含字段详细信息的列表。
九、methods 保存了当前类的方法列表,包含两部分的内容:methods_count和methods[methods_count]
methods_count是该类或者接口显示定义的方法的数量。
method[]是包含方法信息的一个详细列表。
十、attributes 包含了当前类的attributes列表,包含两部份内容:attributes_count 和 attributes[attributes_count]
class文件的最后一部分是属性,它描述了该类或者接口所定义的一些属性信息。attributes_count指的是attributes列表中包含的attribute_info的数量。
属性能够出如今class文件的不少地方,而不仅是出如今attributes列表里。若是是attributes表里的属性,那么它就是对整个class文件所对应的类或者接口的描述;若是出如今fileds的某一项里,那么它就是对该字段额外信息的描述;若是出如今methods的某一项里,那么它就是对该方法额外信息的描述。
22 模拟一个数据库死锁?如何解决死锁问题
http://blog.csdn.net/hexieshangwang/article/details/47189213
23 mysql如何实现分页功能?
24 若是有一百万的数据,mysql如何实现高性能分页
25 数据库三个范式分别是什么?
26 堆排序时间复杂度,nlogn红黑树时间复杂度logn
27 jdk的bin目录下有哪些工具?怎么用?
28 类加载机制是什么,为何实现双亲委派模型?
http://www.cnblogs.com/wxd0108/p/6681618.html
29 java的异常如何分类?
30 分布式的二阶段提交算法
可用于分布式任务
31 post和get有什么区别
32 ThreadLocal有什么问题 内存溢出 this.thread -> threadlocalmap ->(threadlocal实例,而后value)
33 不加锁实现阻塞队列
2017-9-12
三次握手:
第一次握手:创建链接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时本身也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP链接成功)状态,完成三次握手。
· 客户端先发送FIN,进入FIN_WAIT1状态
· 服务端收到FIN,发送ACK,进入CLOSE_WAIT状态,客户端收到这个ACK,进入FIN_WAIT2状态
· 服务端发送FIN,进入LAST_ACK状态
· 客户端收到FIN,发送ACK,进入TIME_WAIT状态,服务端收到ACK,进入CLOSE状态
· 客户端TIME_WAIT持续2倍MSL时长,在linux体系中大概是60s,转换成CLOSE状态
能不能发送完ACK以后不进入TIME_WAIT就直接进入CLOSE状态呢?不行的,这个是为了TCP协议的可靠性,因为网络缘由,ACK可能会发送失败,那么这个时候,被动一方会主动从新发送一次FIN,这个时候若是主动方在TIME_WAIT状态,则还会再发送一次ACK,从而保证可靠性。那么从这个解释来讲,2MSL的时长设定是能够理解的,MSL是报文最大生存时间,若是从新发送,一个FIN+一个ACK,再加上不按期的延迟时间,大体是在2MSL的范围。
回到上面的问题,go写了一个HTTP服务,压测发现TIME_WAIT过多。
首先判断是否是压测程序放在服务的同一台机器...固然不会犯这么低级的错误...
那么这个感受就有点奇怪了,HTTP服务并无依赖外部mysql或者redis等服务,就是一个简单的Hello world,而TIME_WAIT的是主动断开方才会出现的,因此主动断开方是服务端?
答案是是的。在HTTP1.1协议中,有个Connection头,Connection有两个值,close和keep-alive,这个头就至关于客户端告诉服务端,服务端你执行完成请求以后,是关闭链接仍是保持链接,保持链接就意味着在保持链接期间,只能由客户端主动断开链接。还有一个keep-alive的头,设置的值就表明了服务端保持链接保持多久。
HTTP默认的Connection值为close,那么就意味着关闭请求的一方几乎都会是由服务端这边发起的。那么这个服务端产生TIME_WAIT过多的状况就很正常了。
虽然HTTP默认Connection值为close,可是如今的浏览器发送请求的时候通常都会设置Connection为keep-alive了。因此,也有人说,如今没有必要经过调整参数来使TIME_WAIT下降了。
短链接与长链接
通俗来说,浏览器和服务器每进行一次通讯,就创建一次链接,任务结束就中断链接,即短链接。相反地,假如通讯结束(如完成了某个HTML文件的信息获取)后保持链接则为长链接。在HTTP/1.0中,默认使用短链接。从HTTP/1.1起,默认使用长链接,这样作的优势是显而易见的,一个网页的加载可能须要HTML文件和多个CSS或者JS,假如每获取一个静态文件都创建一次链接,那么就太浪费时间了,而在保持链接的状况下,继续GET便可。
对于频繁请求资源的客户来讲,较适用长链接。但链接数最好进行限制,防止创建太多链接拖累服务端。通常浏览器对一个网站的链接是有限制的几个,因此网站会将资源部署在多个域名上以实现浏览器同时请求。
短/长链接应当在TCP链接的范畴中来讨论。有人常说HTTP的短链接和长链接如何如何,可是HTTP只是一个应用层协议,又是无状态的,最终实质性的保持链接仍是得靠传输层,即TCP。
举个例子,NginX做为代理的一种常见配置方式是在NginX与客户端之间的链接使用长链接,NginX与后端服务器之间的链接使用短链接。
keep-alive
咱们使用浏览器的开发者工具查看网络请求和响应信息时常常在HTTP请求头部看到Connection: keep-alive,通常的浏览器都会带着个头去请求数据,假若有特殊需求能够用Connection: close断开。HTTP头部的Connection也不必定就被客户端或服务端老老实实地遵循,毕竟各有各的考虑,尤为是在HTTP/1.0这还只是个实验性的功能,而在HTTP/1.1默认长链接因而没有对长链接作特殊的规定。
长链接也不能无限期地长,服务端有可能在头部放Keep-Alive,其中timeout等于一个值来规定保持链接的秒数,还能够用max来规定多少次请求后断开。若是没有说明怎么断开,主动发起四次握手也能够实现链接的断开。
如今有一个问题就是HTTP的keep-alive与TCP的keep-alive究竟是什么关系。其实这是两种不一样的机制,能够认为没有什么关系。HTTP在头部的Connection中声明keep-alive能够告诉对方要长链接不当即断开,可是TCP的keep-alive则是一种检查对方是否仍旧和本身保持着链接的机制以免自做多情半开放的链接。假如发出一个探测段,成功收到响应,这证实链接正常保持;假如发出一个探测段一段时间后,一个响应都没收到,对方可能已挂断、机器异常或网络异常;假如对方收到探测段但重置,说明原来的链接已经由于某些缘由挂断,目前是由于未进行三次握手新创建链接而被挂断。
算法性能测试?压力测试
互斥锁信号量
信号量与普通整型变量的区别:
①信号量(semaphore)是非负整型变量,除了初始化以外,它只能经过两个标准原子操做:wait(semap) , signal(semap) ;来进行访问;
②操做也被成为PV原语(P来源于Dutch proberen"测试",V来源于Dutch verhogen"增长"),而普通整型变量则能够在任何语句块中被访问;
信号量与互斥锁之间的区别:
1. 互斥量用于线程的互斥,信号线用于线程的同步。
这是互斥量和信号量的根本区别,也就是互斥和同步之间的区别。
互斥:是指某一资源同时只容许一个访问者对其进行访问,具备惟一性和排它性。但互斥没法限制访问者对资源的访问顺序,即访问是无序的。
同步:是指在互斥的基础上(大多数状况),经过其它机制实现访问者对资源的有序访问。在大多数状况下,同步已经实现了互斥,特别是全部写入资源的状况一定是互斥的。少数状况是指能够容许多个访问者同时访问资源
2.互斥量值只能为0/1,信号量值能够为非负整数。
也就是说,一个互斥量只能用于一个资源的互斥访问,它不能实现多个资源的多线程互斥问题。信号量能够实现多个同类资源的多线程互斥和同步。当信号量为单值信号量是,也能够完成一个资源的互斥访问。
3.互斥量的加锁和解锁必须由同一线程分别对应使用,信号量能够由一个线程释放,另外一个线程获得。
项目的系统架构图》》》》
功能的流程图》》》
软件架构方面硬件架构方面
剥洋葱:客户端(技术)服务器(登陆服务器业务逻辑服务器数据库服务器)每一个服务器的业务需求。
服务器卡顿怎么排查:
free,top,iostat等等看看CPU,内存,网络状况
阻塞”与"非阻塞"与"同步"与“异步"不能简单的从字面理解,提供一个从分布式系统角度的回答。
1.同步与异步
同步和异步关注的是消息通讯机制 (synchronous communication/ asynchronous communication)
所谓同步,就是在发出一个*调用*时,在没有获得结果以前,该*调用*就不返回。可是一旦调用返回,就获得返回值了。
换句话说,就是由*调用者*主动等待这个*调用*的结果。
而异步则是相反,*调用*在发出以后,这个调用就直接返回了,因此没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会马上获得结果。而是在*调用*发出后,*被调用者*经过状态、通知来通知调用者,或经过回调函数处理这个调用。
典型的异步编程模型好比Node.js
举个通俗的例子:
你打电话问书店老板有没有《分布式系统》这本书,若是是同步通讯机制,书店老板会说,你稍等,”我查一下",而后开始查啊查,等查好了(多是5秒,也多是一天)告诉你结果(返回结果)。
而异步通讯机制,书店老板直接告诉你我查一下啊,查好了打电话给你,而后直接挂电话了(不返回结果)。而后查好了,他会主动打电话给你。在这里老板经过“回电”这种方式来回调。
2.阻塞与非阻塞
阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.
阻塞调用是指调用结果返回以前,当前线程会被挂起。调用线程只有在获得结果以后才会返回。
非阻塞调用指在不能马上获得结果以前,该调用不会阻塞当前线程。
仍是上面的例子,
你打电话问书店老板有没有《分布式系统》这本书,你若是是阻塞式调用,你会一直把本身“挂起”,直到获得这本书有没有的结果,若是是非阻塞式调用,你无论老板有没有告诉你,你本身先一边去玩了, 固然你也要偶尔过几分钟check一下老板有没有返回结果。
在这里阻塞与非阻塞与是否同步异步无关。跟老板经过什么方式回答你结果无关。
若是是关心blocking IO/ asynchronous IO, 参考 Unix Network Programming View Book
linux进程间通信的几种方式的特色和优缺点,和适用场合
因为不一样的进程运行在各自不一样的内存空间中.一方对于变量的修改另外一方是没法感知的.所以.进程之间的信息传递不可能经过变量或其它数据结构直接进行,只能经过进程间通讯来完成。
管道 ( pipe ):
管道是一种半双工的通讯方式,数据只能单向流动,并且只能在具备亲缘关系的进程间使用。进程的亲缘关系一般是指父子进程关系。 有名管道 (named pipe) :
有名管道也是半双工的通讯方式,可是它容许无亲缘关系进程间的通讯。
信号量( semophore ):
信号量是一个计数器,能够用来控制多个进程对共享资源的访问。
它常做为一种锁机制,防止某进程正在访问共享资源时,其余进程也访问该资源。所以,主要做
为进程间以及同一进程内不一样线程之间的同步手段。 # 消息队列( message queue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识
符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
信号 ( sinal ) :
信号是一种比较复杂的通讯方式,用于通知接收进程某个事件已经发生。
#共享内存( shared memory):共享内存就是映射一段能被其余进程所访问的内存,这段共享内存由一个进程建立,但多个进程均可以访问。共享内存是最快的IPC
方式,它是针对其余进程间通讯方式运行效率低而专门设计的。它每每与其余通讯机制,
如信号量,配合使用,来实现进
程间的同步和通讯。
# 套接字( socket ) :
套解口也是一种进程间通讯机制,与其余通讯机制不一样的是,它可用于不一样及其间的进程通讯。
管道的主要局限性正体如今它的特色上:
只支持单向数据流;
只能用于具备亲缘关系的进程之间; 没有名字;
管道的缓冲区是有限的(管道制存在于内存中,在管道建立时,为缓冲区分配一个页面大小);
管道所传送的是无格式字节流,这就要求管道的读出方和写入方必须事先约定好数据的格式,好比多少字节算做一个消息(或命令、或记录)等等;
管道通讯(PIPE)
两个进程利用管道进行通讯时.发送信息的进程称为写进程.接收信息的进程称为读进程。管道通讯方式的中间介质就是文件.一般称这种文件为管道文件.它就像管道同样将一个写进程和一个读进程链接在一块儿,实现两个进程之间的通讯。写进程经过写入端(发送端)往管道文件中写入信息;读进程经过读出端(接收端)从管道文件中读取信息。两个进程协调不断地进行写和读,便会构成双方经过管道传递信息的流水线。
利用系统调用PIPE()能够建立一个无名管道文件,一般称为无名管道或PIPE;利用系统调用MKNOD()能够建立一个有名管道文件.一般称为有名管道或FIFO。无名管道是一种非永
久性的管道通讯机构.当它访问的进程所有终止时,它也将随之被撤消。无名管道只能用在具备家族联系的进程之间。有名管道能够长期存在于系统之中.并且提供给任意关系的进程使用,可是使用不当容易致使出错.因此操做系统将命名管道的管理权交由系统来加以控制管道文件被建立后,能够经过系统调用WRITE()和READ()来实现对管道的读写操做;通讯完后,可用CLOSE()将管道文件关闭。
消息缓冲通讯(MESSAGE)
多个独立的进程之间能够经过消息缓冲机制来相互通讯.这种通讯的实现是以消息缓冲区为中间介质.通讯双方的发送和接收操做均以消息为单位。在存储器中,消息缓冲区被组织成队列,一般称之为消息队列。消息队列一旦建立后便可由多进程共享.发送消息的进程能够在任意时刻发送任意个消息到指定的消息队列上,并检查是否有接收进程在等待它所发送的消息。如有则唤醒它:而接收消息的进程能够在须要消息的时候到指定的消息队列上获取消息.若是消息尚未到来.则转入睡眠状态等待。
共享内存通讯(SHARED MEMORY)
针对消息缓冲须要占用CPU进行消息复制的缺点.OS提供了一种进程间直接进行数据交换的通讯方式一共享内存 顾名思义.这种通讯方式容许多个进程在外部通讯协议或同步,互斥机制的支持下使用同一个内存段(做为中间介质)进行通讯.它是一种最有效的数据通讯方式,其特色是没有中间环节.直接将共享的内存页面经过附接.映射到相互通讯的进程各自的虚拟地址空间中.从而使多个进程能够直接访问同一个物理内存页面.如同访问本身的私有空间同样(但实质上不是私有的而是共享的)。所以这种进程间通讯方式是在同一个计算机系统中的诸进程间实现通讯的最快捷的方法.而它的局限性也在于此.即共享内存的诸进程必须共处同一个计算机系统.有物理内存能够共享才行。
三种方式的特色(优缺点):
1.无名管道简单方便.但局限于单向通讯的工做方式.而且只能在建立它的进程及其子孙进程之间实现管道的共享:有名管道虽然能够提供给任意关系的进程使用.可是因为其长期存在于系统之中,使用不当容易出错。
2.消息缓冲能够再也不局限于父子进程.而容许任意进程经过共享消息队列来实现进程间通讯.并由系统调用函数来实现消息发送和接收之间的同步.从而使得用户在使用消息缓冲进行通讯时再也不须要考虑同步问题.使用方便,可是信息的复制须要额外消耗CPU的时间.不适宜于信息量大或操做频繁的场合。
3.共享内存针对消息缓冲的缺点改而利用内存缓冲区直接交换信息,无须复制,快捷、信息量大是其优势。可是共享内存的通讯方式是经过将共享的内存缓冲区直接附加到进程的虚拟地址空间中来实现的.所以,这些进程之间的读写操做的同步问题操做系统没法实现。必须由各进程利用其余同步工具解决。另外,因为内存实体存在于计算机系统中.因此只能由处于同一个计算机系统中的诸进程共享。不方便网络通讯。
MySQL实现了四种通讯协议
1. TCP/IP协议,一般咱们经过来链接MySQL,各类主要编程语言都是根据这个协议实现了链接模块
2. Unix Socket协议,这个一般咱们登入MySQL服务器中使用这个协议,由于要使用这个协议链接MySQL须要一个物理文件,文件的存放位置在配置文件中有定义,值得一提的是,这是全部协议中最高效的一个。
一、介绍Java中全部的集合;
二、ArrayList和LinkedList的增删改查的效率问题;
三、Set,Map和List集合共同继承什么类;
四、介绍同步锁,使用情景,均可以再哪里使用;
五、假若有两个线程,一个线程A,一个线程B都会访问一个加锁方法,可能存在并发状况,可是线程B访问频繁,线程A访问次数不多,问如何优化。(我第一次遇到这个问题,说不会,而后面试官说有了解太重度锁和轻度锁吗)
六、介绍下线程和进程的关系;
七、进程间都有哪些通讯方式;
八、讲一下AIDL;
九、了解Handler机制吗,讲解下;
十、MessageQueue的工做原理;
十一、假若有一个一秒和三秒延迟的消息在MessageQueue里面,请问在加入一个两秒延迟的消息插入顺序是怎样的;
十二、假如消息队列里有3个消息,分别是延迟1秒,延迟2秒,延迟3秒,若是1秒的已经消耗了500毫秒,这时延迟2秒的会变成1.5秒,而且在插入一个2秒的会排在1.5秒以后,请讲解下这个原理;
1三、这个算法,给纸和笔,有一个整数,转换为二进制,请找出全部的1的数量;
1四、你以为Java是彻底面相对象的语言吗?
面向对象是一种约束规范,并非绝对的,好比静态属性好比int这些
1五、讲解下你对抽象,多态的理解;
1六、讲解下安卓的四大组建,对哪一个比较熟;
1七、Activity的生命周期;
1八、那你讲下,Activity中的onCreate方法里调用finish方法后,会调用哪些方法;
1九、讲解下安卓的网络请求,httpclient了解过吗,讲解下Java里调用网络的累都有哪些;
20、讲解下http请求里的header有什么做用;
2一、讲解下本身的项目,同时还现场去个人GitHub里看个人开源项目;
2二、有什么想问个人,我问了个人缺点和优点;
介绍本身。
Tcp和udp的区别。分别适用于哪些场景。
可靠链接面向数据流面向报文(实时通信视频)(文件http)
三次握手四次挥手。。是否能够两次握手,为什么要四次挥手。
微服务相关。
Get和post区别。
Http协议相关。
Java有没有多继承,接口和抽象类区别。jvm 理解
jre和jdk的区别
数据库四个范式的区别。在设计数据库的时候如何考量。
为了创建冗余较小、结构合理的数据库,设计数据库时必须遵循必定的规则。在关系型数据库中这种规则就称为范式。范式是符合某一种设计要求的总结。要想设计一个结构合理的关系型数据库,必须知足必定的范式。
在实际开发中最为常见的设计范式有三个:
第一范式是最基本的范式。若是数据库表中的全部字段值都是不可分解的原子值,就说明该数据库表知足了第一范式。
第一范式的合理遵循须要根据系统的实际需求来定。好比某些数据库系统中须要用到“地址”这个属性,原本直接将“地址”属性设计成一个数据库表的字段就行。可是若是系统常常会访问“地址”属性中的“城市”部分,那么就非要将“地址”这个属性从新拆分为省份、城市、详细地址等多个部分进行存储,这样在对地址中某一部分操做的时候将很是方便。这样设计才算知足了数据库的第一范式,以下表所示。
上表所示的用户信息遵循了第一范式的要求,这样在对用户使用城市进行分类的时候就很是方便,也提升了数据库的性能。
第二范式在第一范式的基础之上更进一层。第二范式须要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不能够把多种数据保存在同一张数据库表中。
好比要设计一个订单信息表,由于订单中可能会有多种商品,因此要将订单编号和商品编号做为数据库表的联合主键,以下表所示。
订单信息表
这样就产生一个问题:这个表中是以订单编号和商品编号做为联合主键。这样在该表中商品名称、单位、商品价格等信息不与该表的主键相关,而仅仅是与商品编号相关。因此在这里违反了第二范式的设计原则。
而若是把这个订单信息表进行拆分,把商品信息分离到另外一个表中,把订单项目表也分离到另外一个表中,就很是完美了。以下所示。
这样设计,在很大程度上减少了数据库的冗余。若是要获取订单的商品信息,使用商品编号到商品信息表中查询便可。
第三范式须要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
好比在设计一个订单数据表的时候,能够将客户编号做为一个外键和订单表创建相应的关系。而不能够在订单表中添加关于客户其它信息(好比姓名、所属公司等)的字段。以下面这两个表所示的设计就是一个知足第三范式的数据库表。
这样在查询订单信息的时候,就能够使用客户编号来引用客户信息表中的记录,也没必要在订单信息表中屡次输入客户信息的内容,减少了数据冗余。
第一范式:具备原子性
第二范式:主键列与非主键列遵循彻底函数依赖关系
第三范式:非主键列之间没有传递函数依赖关系
在您开始阅读这篇文章以前,我得明确地告诉您,我并非一个数据库设计领域的大师。如下列出的 11 点是我对本身在平时项目实践和阅读中学习到的经验总结出来的我的看法。我我的认为它们对个人数据库设计提供了很大的帮助。实属一家之言,欢迎拍砖 : )
我之因此写下这篇这么完整的文章是由于,不少开发者一参与到数据库设计,就会很天然地把 “三范式” 看成银弹同样来使用。他们每每认为遵循这个规范就是数据库设计的惟一标准。因为这种心态,他们每每尽管一路碰壁也会坚持把项目作下去。
你们都说标准规范是重要的指导方针而且也这么作着,可是把它看成石头上的一块标记来记着(死记硬背)仍是会带来麻烦的。如下 11 点是我在数据库设计时最优先考虑的规则。
◆规则 1:弄清楚将要开发的应用程序是什么性质的(OLTP 仍是 OPAP)?
当你要开始设计一个数据库的时候,你应该首先要分析出你为之设计的应用程序是什么类型的,它是 “事务处理型”(Transactional) 的仍是 “分析型” (Analytical)的?你会发现许多开发人员采用标准化作法去设计数据库,而不考虑目标程序是什么类型的,这样作出来的程序很快就会陷入性能、客户定制化的问题当中。正如前面所说的,这里有两种应用程序类型, “基于事务处理” 和 “基于分析”,下面让咱们来了解一下这两种类型究竟说的是什么意思。
事务处理型:这种类型的应用程序,你的最终用户更关注数据的增查改删(CRUD,Creating/Reading/Updating/Deleting)。这种类型更加官方的叫法是 “OLTP” 。
分析型:这种类型的应用程序,你的最终用户更关注数据分析、报表、趋势预测等等功能。这一类的数据库的 “插入” 和 “更新” 操做相对来讲是比较少的。它们主要的目的是更加快速地查询、分析数据。这种类型更加官方的叫法是 “OLAP” 。
那么换句话说,若是你认为插入、更新、删除数据这些操做在你的程序中更为突出的话,那就设计一个规范化的表不然的话就去建立一个扁平的、不规范化的数据库结构。
如下这个简单的图表显示了像左边 Names 和 Address 这样的简单规范化的表,怎么经过应用不规范化结构来建立一个扁平的表结构。
◆规则 2:将你的数据按照逻辑意义分红不一样的块,让事情作起来更简单
这个规则其实就是 “三范式” 中的第一范式。违反这条规则的一个标志就是,你的查询使用了不少字符串解析函数
例如 substring、charindex 等等。若真如此,那就须要应用这条规则了。
好比你看到的下面图片上有一个有学生名字的表,若是你想要查询学生名字中包含“Koirala”,但不包含“Harisingh”的记录,你能够想象一下你将会获得什么样的结果。
因此更好的作法是将这个字段拆分为更深层次的逻辑分块,以便咱们的表数据写起来更干净,以及优化查询。
◆规则 3:不要过分使用 “规则 2”
开发者都是一群很可爱的生物。若是你告诉他们这是一条解决问题的正路,他们就会一直这么作下去,作到过了头致使了一些没必要要的后果。这也能够应用于咱们刚刚在前面提到的规则2。当你考虑字段分解时,先暂停一下,而且问问你本身是否真的须要这么作。正如所说的,分解应该是要符合逻辑的。
例如,你能够看到电话号码这个字段,你不多会把电话号码的 ISD 代码单独分开来操做(除非你的应用程序要求这么作)。因此一个很明智的决定就是让它保持原样,不然这会带来更多的问题。
◆规则 4:把重复、不统一的数据当成你最大的敌人来对待
集中那些重复的数据而后重构它们。我我的更加担忧的是这些重复数据带来的混乱而不是它们占用了多少磁盘空间。
例以下面这个图表,你能够看到 "5th Standard" 和 "Fifth standard" 是同样的意思,它们是重复数据。如今你可能会说是因为那些录入者录入了这些重复的数据或者是差劲的验证程序没有拦住,让这些重复的数据进入到了你的系统。如今,若是你想导出一份将本来在用户眼里十分困惑的数据显示为不一样实体数据的报告,该怎么作呢?
解决方法之一是将这些数据完整地移到另一个主表,而后经过外键引用过来。在下面这个图表中你能够看到咱们是如何建立一个名为 “Standards”(课程级别) 的主表,而后一样地使用简单的外键链接过去。
◆规则 5:小心被分隔符分割的数据,它们违反了“字段不可再分”
前面的规则 2 即“第一范式”说的是避免 “重复组” 。下面这个图表做为其中的一个例子解释了 “重复组”是什么样子的。若是你仔细的观察 syllabus(课程) 这个字段,会发如今这一个字段里实在是填充了太多的数据了。像这些字段就被称为 “重复组” 了。若是咱们又得必须使用这些数据,那么这些查询将会十分复杂而且我也怀疑这些查询会有性能问题。
这些被塞满了分隔符的数据列须要特别注意,而且一个较好的办法是将这些字段移到另一个表中,使用外键链接过去,一样地以便于更好的管理。
那么,让咱们如今就应用规则2(第一范式) “避免重复组” 吧。你能够看到上面这个图表,我建立了一个单独的 syllabus(课程) 表,而后使用 “多对多” 关系将它与 subject(科目) 表关联起来。
经过这个方法,主表(student 表)的 syllabus(课程) 字段就再也不有重复数据和分隔符了。
◆规则 6:小心那些仅仅部分依赖主键的列
留心注意那些仅仅部分依赖主键的列。例如上面这个图表,咱们能够看到这个表的主键是 Roll No.+Standard。如今请仔细观察 syllabus 字段,能够看到 syllabus(课程) 字段仅仅关联(依赖) Standard(课程级别) 字段而不是直接地关联(依赖)某个学生(Roll No. 字段)。
Syllabus(课程) 字段关联的是学生正在学习的哪一个课程级别(Standard 字段)而不是直接关联到学生自己。那若是明天咱们要更新教学大纲(课程)的话还要痛苦地为每一个同窗也修改一下,这明显是不符合逻辑的(不正常的作法)。更有意义的作法是将这些字段从这个表移到另一个表,而后将它们与 Standard(课程级别)表关联起来。
你能够看到咱们是如何移动 syllabus(课程)字段而且一样地附上 Standard 表。
这条规则只不过是 “三范式” 里的 “第二范式”:“全部字段都必须完整地依赖主键而不是部分依赖”。
◆规则 7:仔细地选择派生列
若是你正在开发一个 OLTP 型的应用程序,那强制不去使用派生字段会是一个很好的思路,除非有迫切的性能要求,好比常常须要求和、计算的 OLAP 程序,为了性能,这些派生字段就有必要存在了。
经过上面的这个图表,你能够看到 Average 字段是如何依赖 Marks 和 Subjects 字段的。这也是冗余的一种形式。所以对于这样的由其余字段获得的字段,须要思考一下它们是否真的有必要存在。
这个规则也被称为 “三范式” 里的第三条:“不该该有依赖于非主键的列” 。 个人我的见解是不要盲目地运用这条规则,应该要看实际状况,冗余数据并不老是坏的。若是冗余数据是计算出来的,看看实际状况再来决定是否应用这第三范式。
◆规则 8:若是性能是关键,不要执拗地去避免冗余
不要把 “避免冗余” 看成是一条绝对的规则去遵循。若是对性能有迫切的需求,考虑一下打破常规。常规状况下你须要作多个表的链接操做,而在很是规的状况下这样的多表链接是会大大地下降性能的。
◆规则 9:多维数据是各类不一样数据的聚合
OLAP 项目主要是解决多维数据问题。好比你能够看看下面这个图表,你会想拿到每一个国家、每一个顾客、每段时期的销售额状况。简单的说你正在看的销售额数据包含了三个维度的交叉。
为这种状况作一个实际的设计是一个更好的办法。简单的说,你能够建立一个简单的主要销售表,它包含了销售额字段,经过外键将其余全部不一样维度的表链接起来。
◆规则 10:将那些具备“名值表”特色的表统一块儿来设计
不少次我都遇到过这种 “名值表” 。 “名值表” 意味着它有一些键,这些键被其余数据关联着。好比下面这个图表,你能够看到咱们有 Currency(货币型)和 Country(国家)这两张表。若是你仔细观察你会发现实际上这些表都只有键和值。
对于这种表,建立一个主要的表,经过一个 Type(类型)字段来区分不一样的数据将会更有意义。
◆规则 11:无限分级结构的数据,引用本身的主键做为外键
咱们会常常碰到一些无限父子分级结构的数据(树形结构?)。例如考虑一个多级销售方案的状况,一个销售人员之下能够有多个销售人员。注意到都是 “销售人员” 。也就是说数据自己都是一种。可是层级不一样。这时候咱们能够引用本身的主键做为外键来表达这种层级关系,从而达成目的。
这篇文章的用意不是叫你们不要遵循范式,而是叫你们不要盲目地遵循范式。根据你的项目性质和须要处理的数据类型来作出正确的选择。
详细设计数据库步骤。
1、关于java基础
一、一致性hash
(1)提出一致性hash是为了解决什么问题?
(2)hash的性能评估指标(单调性、容错性、可扩展性)
二、java锁机制
(1)synchronized关键字、volatile关键字
(2)java.util.concurrent.locks包
(3)synchronized和ReentrantLock(重入锁)的区别,synchronized用在代码块、方法、静态方法时锁的都是什么
三、ConcurrentHashMap的原理,都用的是哪一种锁,segment有没可能增大(不会,只会增大每一个segment中的entry数组)
四、进程和线程的区别
五、AtomicInteger实现原理(CAS自旋)
六、值传递和引用传递
七、java有没有多继承,接口和抽象类区别
八、jdk和jre的区别
九、讲述一下并发编程与多线程
十、String、StringBuffer和StringBuilder的区别
十一、int在32位和64位机中的区别
十二、java中基本类型的位数
1三、static关键字的用法
1四、java的访问权限,成员的可见性
1五、HashmMap、HashTable、ConcurrentHashMap的区别与联系
1六、char可否存储汉字?
1七、Spring转成int型,能不能转,怎么转
1八、HashMap和HashSet的实现原理
1九、动态代理的原理
20、包装类型和基本数据类型的比较问题(例如:Integer可否== int类型变量,可否作比较,何时不能作比较)
2一、ArrayList和LinkedList的比较
2二、单例模式都有什么,是否线程安全,怎么改进(从synchronized到双重检验锁到枚举)
2三、java线程安全都体如今哪些方面,如何维护线程安全?
2四、反射机制中能够获取private成员的值吗(没有set和get函数)
2五、写一段synchronized可能发生死锁的代码
2六、死锁的条件,摒弃死锁的条件有哪些?
2、关于java虚拟机
一、垃圾回收算法,为何要分代处理
二、GC停顿缘由,如何下降停顿
三、JVM如何调优,参数怎么调
四、如何使用工具分析jvm状态
五、类加载机制
六、什么是java虚拟机,对jvm的理解
七、jvm内存模型,各个区的做用
八、堆的做用
九、JVM调试工具
十、堆和栈的区别
十一、内存溢出了怎么办
十二、何时会栈溢出
3、关于java后台
一、介绍Spring的IOC和AOP,分别是如何实现的(反射机制和动态代理)
二、redis如何处理分布式服务器并发形成的不一致,若是数据库不提供隔离呢?
三、解释MySQL索引、b树,为啥不用平衡二叉树或红黑树(磁盘与内存的存储方式不一样)
四、Spring的bean加载机制,bean生成的具体步骤
五、IOC的注入方式(set注入、构造方法注入)
六、Spring什么时候建立applicationContext(web.xml中使用listener)
七、listener是监听哪一个事件
八、SpringMVC的具体流程
九、Spring的特性,SpringMVC中控制器的名字及其配置
十、Spring用到哪些设计模式?
十一、controller怎么处理的请求
4、关于数据结构与算法
一、01矩阵,相邻的1是一个岛屿,找出全部岛屿数(递归解决)
二、2个鸡蛋,100高的楼,最少的次数测出鸡蛋碎掉的临界层,没碎的鸡蛋能够反复使用
三、大量字符串找出数量最多的K个,考虑内存放得下和放不下两种状况
四、跳表的基本原理
五、最长回文子串
六、找到数组中最多的那个数,除了hashset还有没有其余方法(蒙特卡罗法)
七、输入合法的数字字符串,输出货币字符(就是每隔三位加逗号,考虑边界处理)
八、有1-10 10个数,和一个数sum,计算用10个数连加获得sum有多少种系数组合(递归)
九、如何实现高效的同步链表
十、层次遍历二叉树,偶数层输出,且逆序输出
十一、给定一个字符串,写出全部可能的全排列(递归)
十二、5亿条淘宝交易订单,输出销售次数最多的100个商品。
1三、给出年月日,如何求出这天是这年的第几天?
1四、64个马有8个跑道,没有计时工具,最少须要多少次跑,能够找到跑的最快的那个马,若是换成找到最快的四匹呢?
1五、给一个函数,返回0和1,几率为p和1-p,请你实现一个函数,使得返回0和1的几率同样
1六、10亿个url,每一个url大小小于56B,要求去重,内存4G
1七、吧一个BST转化成一个双向链表
1八、手写一个全排列
1九、B数和B+数
20、介绍一下hash,怎么解决hash冲突
2一、给一个文件,找出其中每一个单词的个数
2二、1000瓶药有1瓶有毒,若是小白鼠服用有毒的药,则24小时后死亡。如今需设计一种策略,使用尽量少的小白鼠,在24小时内找出有毒的药。(将串行的二分法并行使用)
5、关于Http协议
一、TCP和UDP的区别,分别适用于哪些场景?
二、三次握手四次握手,是否能够两次握手,为什么要四次握手?
三、get和post的区别
四、Http协议相关
6、关于Linux
一、epoll、epollh和select的区别
二、Linux下的一些指令,怎么查看进程,按照内存大小,CPU占用排序等
7、关于数据库
一、数据库四个范式的区别,在设计数据库的时候怎么考量,详细设计数据库的步骤。
二、MySQL和Oracle的区别,如何选择?
三、SQL中replace和update的区别
四、事务管理acid
五、数据库的索引有什么用,带来的问题是什么?
六、数据库查询时间优化
七、
8、设计模式
一、单例模式
二、生产者模式、消费者模式
文件A100亿记录,文件B100万记录,找出A中不在B中的记录
如何拦截5分钟前恶意登陆(用户名密码不正确)超多必定次数的ip
十二、数据传输:服务器与服务器之间传输文件夹下的文件,一个文件夹下有10个文件,另外一个文件夹下有100个文件,两个文件夹大小相等,问,哪一个传输更快?(http协议)
1三、数据库两个表关联的方式
1四、数据库表关联的内部算法
1五、数据库锁的实现
1六、数据库表里有100万条数据,想要删除80万条数据,可是由于锁的缘由,删除很慢,如今想要快速删除怎么办
网易内推
一面(项目)
1. 项目的架构,怎么实现的
2. 会不会java web的知识
3. 对一个登陆窗口进行测试
4. 测试人员须要的能力
5. 有没有比较熟的b/s架构
二面(测试思惟)(未经过)
1. 写代码:找出一组数中最大的数
2. 所接触到的测试的内容
3. 对淘宝的搜索栏进行测试(1.宝贝,店铺,天猫选项;2.搜索栏;3.搜索按钮)
4. 与他人相比,你的优点(此处最好答热情和测试行业大趋势和前景)
中兴
一面(现场+技术)
1.简单介绍一下本身
2.简单介绍一下项目
3.性能测试有哪些
4.TCP的拥塞控制
5.http中的get和post请求的区别
6.怎么确认post请求发送完毕
7.专利是第一做者么
8.loadrunner用来干了什么
二面(现场+综合面试)
1.英语介绍本身的学校
2.遇到过最大的挫折
3.看什么书,重点讲一本
4.本身的优缺点
5.若是你带领一个团队作一款产品,你想作什么,为何(后面会有无数个坑,压力面的核心)
6.怎么调节负面情绪
7.有什么爱好
58面试
一面(基础)
1.介绍一下项目
2.流行的加密算法(Lz是信息安全方向的硕士,不少面试官都会稍微考考信息安全的问题,考察一下对专业知识的了解)
3.写代码(找出数组中不重复的数)
4.写上述代码的测试用例
5.SQL(写语句,top,count,group by,order by,select)
6.linux(cd..,cd-,mkdir,vi,netstat)
7.java(忘记了)
8.网络(get和post的区别,七层分别是什么,应用层的协议)
9.测试(测试一个系统的性能,具体不记得了)
二面(基础)
1.自我介绍
2.写代码(单例模式)
3.SQL(索引,多表查找)
4.数组和链表的区别
5.hash的用处
6.怎么解决hash冲突
7.linux就不问了
8.DNS劫持的原理
三面(HR)
1.自我介绍
2.有什么符合软件测试岗位的优点
3.用三个词形容本身
4.遇到过什么困难
5.有没有考虑过离乡背井的艰难
美团
一面(基础+项目)
1.介绍项目
2.项目中的模糊检索怎么实现(项目挖的比较深,会一直追着问)
3.项目界面和数据库怎么交互?数据流向
4.项目怎么测试
5.软件测试的基本流程
6.TCP和UDP的区别和应用场景
7.写代码(一个数的个位十位百位相加,判断结果的个位是否是3)
二面(基础+算法)
1.自我介绍
2.讲一下项目
3.java回收机制
4.java内存泄露
5.重载和重写的区别
6.http的关键字
7.TCP和UDP的区别
8.写一个SQL语句
9.group by和order by的区别
10.写代码(全排列)
11.写代码(A to I)
12.上一个代码的测试用例
13.1G数据怎么排序
三面(总监+宏观把控)
1.cookie和session的区别(总监面的每一个问题都会问的比较深,延伸得比较广;并且每一个问题回答完以后都会着“你肯定?再想想”)
2.session存在服务器的哪一个地方
3.在地址栏键入网址以后的过程是什么样的,数据流向,哪个过程最耗时间
4.怎么优化数据库
5.平时怎么学习的
6.java和c++最大的区别
7.有些什么测试方法
8.路由表中存的是什么
9.B/S和C/S架构的区别
10.有没有用过框架
四面(现场+HR)
1.自我介绍
2.最有成就的事
3.遇到过什么挫折
4.优缺点
5.对工做地点有没有要求
6.最想去哪家互联网公司,有什么地方吸引你
7.对美团有什么了解
8.平时喜欢干什么
9.有什么问题
百度
一面(基础)
1.写代码(从数组中找出两个相加等于n的下标)
2.测试三边能不能组成三角形(考测试思惟全面性和逻辑是否清晰)
3.为何报测试
4.常见的测试类型,性能测试指标
5.SQL(多表查询,左连接和右连接的区别)
6.linux(查看一个文档,显示出文档的最后五条数据)
7.JAVA(int和Integer的区别)
8.网络(搜索百度主页的全过程,整个过程的物理设备,网路协议,数据流向;session)
9.怎么与人合做的
10.怎么证实本身学习能力强
11.做为测试的优点
12.怎么考虑工做地点离家远的问题
13.有什么要问的
二面(处理能力+思惟全面性)
1.自我介绍
2.项目的具体算法
3.怎么判断链表有环,并优化(要求写出时间复杂度最优的算法)
4.怎么测试string to int程序(要说的很全面,一直问“还有吗”)
5.平时有什么爱好
6.对测试的了解
7.作测试的优点
8.在一个环形商场里有不少商家,商家的钱数事先知道。让你去抢钱,而且保证不抢连续两家,怎么保证抢钱数目最多
9.让你去实习,能够去么
10.有什么要问的
三面(总监+宏观把控)
1.自我介绍一下
2.你怎么学的测试
3.简单介绍一下项目
4.对工做地点是怎么选择的
5.对测试的一些想法
6.优缺点
7.有什么要问的
滴滴
一面(基础)
1.简单自我介绍一下
2.项目介绍
3.对测试的理解
4.java中的框架
5.了解到的锁的知识
6.进程间通讯的方式
7.写代码(二叉树的非递归后续遍历)
8.对上面的代码写单测
9.linux相关
10.数据库的优化
11.线程的状态转化
12.TCP和UDP的区别
13.详细讲讲拥塞控制
14.java中的集合的底层实现
二面(算法)
1.三人三鬼安全运过河(不详述)
2.两个一样大小的罐子,一个装盐,一个装糖。首先从盐罐舀一勺盐到糖罐,再将糖罐中的混合物搅拌均匀,再从糖罐舀一勺混合物到盐罐,问,最后是糖罐的盐多仍是盐罐的糖多(用公式计算的还不行,要一下就能得出结果的想法)
3.写代码(判断字符串数组是否能够收尾相连成环路)
4.写代码(从int型数组中找出和连续子串,要求和最大)
5.测一个存储系统B(系统B有上级系统A,系统B中有1T存储容量,天天0点定时更新,还有分布式的缓存……)
三面(现场+交叉面)(未经过)
1.自我介绍
2.什么是有效的沟通
3.对一个功能进行压力测试
4.滴滴抢单给出了新思路(大概是就用抢单以后会等10s,对抢单的司机进行最优匹配),让设计整个架构,并列出测试点
5.对滴滴的了解
总结:1.现场要求写代码,最好先理清思路,考虑一下时间复杂度和空间复杂度,能写出最优算法是会加分很多的。(这儿也有坑,某公司的面试官让写了个代码,看完以后问“有没有更加优化的代码?”Lz又看了大概5分钟,确实没想出来。答“想不出来。”面试官笑着说“想不出来是由于的确没有更优的了。我还真怕你给我胡诌一个出来。”Lz“……”。因此回答问题实事求是,按正常的思路走,不会的时候不要乱说);
2.对于每一个知识点,最好说出本身的理解,不要直接背书上的1234点。就拿java中问的比较常见“抽象类和接口的区别”举例。若是你回答1.java中抽象类只能单继承,但能够实现多个接口,2.抽象类中能够有方法的定义与实现,接口中方法不能实现………………这样的回答你们都会,因此若是说完上述这些,再加入一点本身实际学习中的理解会更好。好比:一般,我会把phone定义为一个抽象类,它是各类不一样手机类的一个抽象。然而有的手机具备指纹解锁的功能,有的手机具备防水防尘的功能,对于这些附加的功能,我会把它们分别定义成不一样的接口。当我须要这个功能的时候,在具体的类中再去实现这个功能。这样会更加符合面向对象中高内聚低耦合的特色…………就是这相似这样的回答,会更加突出你学习中的思考过程。
3.既然投了测试,确定会问测试相关的知识,因此仍是得早点看看书,多看看博客,逛逛论坛;
4.面试官都很不错,有的时候会给你一些提示和引导,因此放轻松,太紧张只会思路混乱;
5.通常面试的酒店可能会比较远,保证比约定时间早到30分钟就好了。签到以后整理一下本身的衣着,整洁干净就行。看看笔记,调动一下思惟。
6.最后面试官问你有什么问题的时候必定要问问,Lz以前被某公司内推时的一个HR宣传视频误导了,觉得最后纯粹是面试官客套一下,不用问。以后跟一些面试官的沟经过程中发现应聘者问的问题仍是挺重要的,这个问题会暴露你的关注点。尽可能让面试官了解到你对将来工做细节的关注,让他知道你对这个工做很感兴趣。可是最好不要问关于薪酬,福利的问题,等到谈offer的时候天然会跟你说这些。
一、HTTP请求的过程,越清楚越好(我从dns解析到TCP三次握手,四次挥手,还有后台请求逻辑讲了一遍)
二、Java线程池ThreadPoolEcecutor参数,基本参数,使用场景
三、HashMap、HashTable、CurrentHashMap的区别及场景,说一下你的理解。HashMap的负载因子,干啥用的。
四、ArrayList与LinkedList的区别及使用场景,有没有ArrayList增删效率比LinkedList高的场景。ArrayList底层采用什么实现数据的拷贝。
五、MySQL的ACID讲一下,延伸到隔离级别
六、JMM讲一下,volite关键字及使用场景。
七、JVM的内存布局以及垃圾回收原理及过程讲一下。讲一下CMS垃圾收集器垃圾回收的流程。以及CMS的缺点(忘了。。)
八、 智力题(聊着聊着忽然来个),两个杯子,一个有3升水,一个有5升水,请问如何倒出4升水。。(我回答说,使二者水平面一致。。。。一看到题,就这样啊。。但其答案不是我回答的这。。)
九、 手写二叉树的中序遍历与层序遍历
十、 手写二分查找(很基础)
十一、最后还聊了一下项目,聊一下难点。
十二、最后就是你有什么要问的。一、表现二、大家那边主要用那些java技术三、若是过,啥时通知下一面结果。