赞
踩
简单的介绍一下自己的工作经历与职责,在校或者工作中主要的工作内容,主要负责的内容;(你的信息一清二白的写在简历上,这个主要为了缓解面试者的压力)
介绍下自己最满意的,有技术亮点的项目或平台,重点介绍下自己负责那部分的技术细节;(主要考察应聘者对自己做过的事情是否有清晰的描述,判断做的事情的复杂度)
1.jdk为我们提供了4种类型线程池,通过静态工厂创建,当有请求到来时,若没有达到核心线程的数量则创建核心线程,若达到了就创建非核心线程(超时回收),若达到线程池最大线程数量,则走拒绝策略。
2.使用线程池可以避免频繁创建、销毁线程的开销,并且我们还可以监控线程的运行状态。
3.两种方式创建线程池:new ThreadExecutor(……)或者利用Executors的工厂方法创建。
僵尸线程:一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他,而父进程还没有结束,那么他将变成一个僵尸进程。
危害:进程号被占用,会导致操作系统没有可用的进程号而无法创建进程。
在多线程环境下,运行的结果与我们所期望的结果一致或与单线程运行的结果相同,则认为是线程安全的。
可以通过加锁的方式保证线程安全。或者使用(ThreadLocal类为每个线程操作自己的变量)
cpu密集型:n+1 IO密集型:2n+1
volatile可以保证可见性,禁止指令重排序,如果要求变量修改后立即对其他线程可见,可以使用volatile(双重锁单例);ThreadLocal为每一个线程提供一份单独的变量副本,底层通过ThreadLocalMap实现,key为ThreadLocal类型(弱引用),value为变量值。
因为value会被强引用所引用(来源当前线程)导致无法GC,从而发生内存泄露,进而导致OOM。
预防:每次使用完毕后调用remove()方法自动清除key为null的value。
synchronized可以保证原子性,可见性,顺序性,并且可以作用在方法上,代码块。
synchronized做代码块锁的时候,如果是使用自定义的锁,或者this对象作为锁,那么锁定的是对象,如果对于静态的对象做锁定,那么锁定的就是类了。
volatile只能保证可见性不能保证原子性,并且只能作用于变量,可以禁止指令重排序。
模拟死锁
package DeadLock; public class TestDeadLock implements Runnable { public int i; public static Object o1=new Object(); public static Object o2=new Object(); @Override public void run() { if(i==1) { synchronized(o1) { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized(o2) { System.out.println("1"); } } }else if(i==2){ synchronized(o2) { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized(o1) { System.out.println("2"); } } } } public static void main(String[] args) { TestDeadLock t1=new TestDeadLock(); TestDeadLock t2=new TestDeadLock(); t1.i=1; t2.i=2; new Thread(t1).start(); new Thread(t2).start(); } }
ActiveMQ:单机吞吐量低,但可用性较好,可实现主从架构,功能完备。
RabbitMQ:单机吞吐量低,基于erlang开发,基于
erlang 开发,并发能力很强,性能极好,延时很低。 RocketMQ:在同等机器下,可以支撑大量的topic,分布式架构,支持分布式事务。
Kafak:可用性高,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用,在同等机器下,Kafka 应该尽量保证 topic数量不要过多
RPC是远程过程调用,可以让我们像调用本地方法 一样调用远程方法。
服务消费者(client客户端)通过调用本地服务的方式调用需要消费的服务;
客户端存根(client stub)接收到调用请求后负责将方法、入参等信息序列化(组装)成能够进行网络传输的消息体;
客户端存根(client stub)找到远程的服务地址,并且将消息通过网络发送给服务端;
服务端存根(server stub)收到消息后进行解码(反序列化操作);
服务端存根(server stub)根据解码结果调用本地的服务进行相关处理;
本地服务执行具体业务逻辑并将处理结果返回给服务端存根(server stub);
服务端存根(server stub)将返回结果重新打包成消息(序列化)并通过网络发送至消费方;
客户端存根(client stub)接收到消息,并进行解码(反序列化);
服务消费方得到最终结果;
1.服务提供者在启动时,向注册中心注册自己提供的服务;
2.服务消费者在启动时,向注册中心订阅自己所需的服务;
3.注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者;
4.服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用;
5.服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心;
Random LoadBalance 随机,按权重设置随机概率,在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
RoundRobin LoadBalance 轮询,按公约后的权重设置轮询比率,存在慢的提供者累积请求的问题;
LeastActive LoadBalance 最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
ConsistentHash LoadBalance 一致性 Hash,相同参数的请求总是发到同一提供者。
并发控制就是限制占用的线程池线程数。
(1)服务端并发执行(或占用线程池线程数)不能超过10个。
<dubbo:service interface="com.foo.BarService" executes="10" />
(2)限制到方法
<dubbo:service interface="com.foo.BarService">
<dubbo:method name="sayHello" executes="10" />
</dubbo:service>
(3)占用连接的请求的数不能超过10个
<dubbo:service interface="com.foo.BarService" actives="10" />
重试机制:超时重试,一定时间内没有收到ack请求,进行重试操作。
Hystrix 可以让我们在分布式系统中对服务间的调用进行控制,加入一些调用延迟或者依赖故障的容错机制。
Hystrix 通过将依赖服务进行资源隔离,进而阻止某个依赖服务出现故障时在整个系统所有的依赖服务调用中进行蔓延;同时Hystrix 还提供故障时的 fallback 降级机制。
主要特点
Dubbo具有调度、发现、监控、治理等功能,支持相当丰富的服务治理能力。Dubbo架构下,注册中心对等集群,并会缓存服务列表已被数据库失效时继续提供发现功能,本身的服务发现结构有很强的可用性与健壮性,足够支持高访问量的网站。类似于电商等同步调用场景多并且能支撑搭建Dubbo 这套比较复杂环境的成本的产品而言,Dubbo 确实是一个可以考虑的选择。但如果产品业务中由于后台业务逻辑复杂、时间长而导致异步逻辑比较多的话,可能Dubbo 并不合适。同时,对于人手不足的初创产品而言,这么重的架构维护起来也不是很方便。
Spring Cloud由众多子项目组成,可以一站式进行微服务的开发,提供了搭建分布式系统及微服务常用的工具,如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性token、全局锁、选主、分布式会话和集群状态等,满足了构建微服务所需的所有解决方案。
项目中遇到了哪些比较有挑战性的问题,是如何解决的;(这个很有争议,一方面是你连一个复杂的问题都解决不了,要你过来干什么,还有就是,我的能力牛逼啊,但是公司没有业务场景让我展示啊!这个就看你遇到的面试官了,祝你好运!)
看过哪些源代码?然后会根据你说的源码问一些细节的问题?(这里主要考察面试者是否对技术有钻研的精神,还是只停留在表面,还是背了几道面经,这个对于很多有强迫症的面试官,如果你连源码都没看过,基本上是会pass掉的,比如我也是这样的!)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。