阿里一面记录

 因为是电话面试,开门见山,寒暄都没有,直接开始
谈一下你在项目中解决过的比较复杂的问题 (这个其实就是扯自己的项目难点,其实自己对于自己的项目肯定比别人更清楚,灵活应对,一言不合就  可以说我大清自由国情在此)
缓存
      缓存击穿
          现象:查询的某一个数据在缓存中一直不存在,就会造成每一次请求都查询DB,这样缓存就失去了意义
          解决方案:1.缓存空对象 2.单独过滤处理
      缓存并发
          现象:一个缓存失效,出现多个进程同时查询DB,同时设置缓存的情况
          解决方案:缓存查询加锁,如果KEY不存在,就加锁,然后查DB入缓存,然后解锁;其他进程如果发现有锁就等待,然后等解锁后返回数据或者进入DB查询。
      缓存雪崩
          现象:缓存周期性集中失效;
          解决方案:原有的失效时间基础上增加一个随机值,这样每一个缓存的过期时间的重复率就会降低。
      缓存同步
          1.节点监听缓存的状态,如果变了,则通知其他节点,作相应的刷新
          2.各个节点记录自己改变的东西,然后同步到其他节点
      缓存更新
          1.直写模式
     在数据更新时,同时写入缓存Cache和后端存储(DB)。此模式的优点是操作简单;缺点是因为数据修改需要同时写入存储,数据写入速度较慢。
2.回写模式
     在数据更新时只写入缓存Cache。通常由一个后台队列检查缓存中数据的变化,再将据写到后端存储(DB )。此模式的优点是数据写入速度快,因为不需要写存储;缺点是一旦更新后的数据未被写入存储时出现系统掉电的情况,数据将无法找回。
3,更新手段:1.定时轮循2.过期更新3.MySql数据,是可以解析binlog内容,来实现redis更新4.数据库触发器5.第三方组件databus

数据库(限时秒杀系统绝对存在的问题)
     乐观锁与悲观锁
          乐观锁认为一个用户读数据的时候,别人不会去写自己所读的数据;悲观锁就刚好相反,觉得自己读数据库的时候,别人可能刚好在写自己刚读的数据,其实就是持一种比较保守的态度
          悲观锁:开始改变此对象之前就将该对象锁住,并且直到你提交了所作的更改之后才释放锁。悲观的缺陷是不论是页锁还是行锁,加锁的时间可能会很长,这样可能会长时间的限制其他用户的访问,也就是说悲观锁的并发访问性不好。
           乐观锁:直到你准备提交所作的更改时才将对象锁住,当你读取以及改变该对象时并不加锁。可见乐观锁加锁的时间要比悲观锁短,乐观锁可以用较大的锁粒度获得较好的并发访问性能。但会增加并发用户读取对象的次数。

数据结构(基础了)
          ConcurrentHashMap
               1.HashMap未进行线程同步,Hashtable使用了了synchronized性能比较低,不过锁了整个hash表,ConcurrentHashMap将锁的粒度减小到了桶的级别,get,put,remove等常用操作只需要锁用到的桶,Size()等操作需要锁全表,通过 HashEntry 对象的不变性和用 volatile 型变量协调线程间的内存可见性,使得 大多数时候,读操作不需要加锁就可以正确获得值。(<=jdk1.7) https://www.ibm.com/developerworks/cn/java/java-lo-concurrenthashmap/index.html
               2.它摒弃了Segment(锁段)的概念,而是启用了一种全新的方式实现,利用CAS算法。(jdk1.8) http://blog.csdn.net/u010723709/article/details/48007881

JAVA内存模型(看有没有稍微深入研究)
     
     Java语言采用 共享内存模型来实现多线程之间的信息交换和数据同步,Java内存模型的主要目标是定义程序中各个变量的访问规则,即在JVM中将 变量存储到内存和从内存中取出变量这样的底层细节
     JMM规定了所有的变量都存储在主内存(Main Memory)中。每个线程还有自己的工作内存(Working Memory), 线程的工作内存中保存了该线程使用到的变量的主内存的副本拷贝,线程对变量的所有操作(读取、赋值等)都必须在工作内存中进行,而不能直接读写主内存中的变量(volatile变量仍然有工作内存的拷贝,但是由于它特殊的操作顺序性规定,所以看起来如同直接在主内存中读写访问一般)。不同的线程之间也无法直接访问对方工作内存中的变量,线程之间值的传递都需要通过主内存来完成。 线程的working memory只是cpu的寄存器和高速缓存的抽象描述。
      Java内存模型围绕着并发编程中 原子性、可见性、有序性这三个特征来建立.( http://www.cnblogs.com/lewis0077/p/5143268.html)
   1.原子性(Atomicity):一个操作不能被打断,要么全部执行完毕,要么不执行。在这点上有点类似于事务操作,要么全部执行成功,要么回退到执行该操作之前的状态。
     2.可见性:一个线程对共享变量做了修改之后,其他的线程立即能够看到(感知到)该变量这种修改(变化)。
     3.有序性:对于一个线程的代码而言,我们总是以为代码的执行是从前往后的,依次执行的。这么说不能说完全不对,在单线程程序里,确实会这样执行;但是在多线程并发时,程序的执行就有可能出现乱序。
       happens-before原则

如何防止订单重复提交 (我估计写web的都深受重复提交表单的毒害)
1.前端限制2.增加随机数3.  One-Time Tokens 4 .验证码

你可能感兴趣的:(阿里一面记录)