高级部分
1、分布式集群下的session方案:
(1)基于ip_hash策略,将同一用户的请求都集中在一台服务器上,即某请求会一直与某台服务器保持连接
(2)tomcat的session复制
(3)cache db中存储,就是token的概念
2、nginx的主要功能?
(1)正向代理:代理服务器代理客户端,转发请求,并将获得的内容返回给客户端。功能为,如fanqiang
(2)反向代理:代理服务器就像是原始服务器,代理目标web节点返回结果。功能为,如负载均衡
(3)负载均衡:将大量用户请求分配到多台机器处理,并且其中一台宕机,其它正常,则不会影响用户正常请求
3、nginx与zookeeper的区别?
(1)nginx管理配置成本较高,zookeeper可以很方便的维护配置信息
(2)nginx单点故障时,维护成本较高。zookeeper会自动通知调用者重新获取服务列表
(3)nginx有内置负载均衡策略,而zookeeper没有,需要自己实现
(4)nginx相比zookeeper有更大的吞吐量
4、缓存中,如redis存在脏数据怎么办?
(1)使用分布式锁,确保原子性
(2)弥补性操作,晚上跑批进行数据同步
5、dubbo概念?功能?
(1)概念:远程调用的分布式框架
(2)功能:
- 透明的方法调用,就像调用本地方法一样简单
- 负载均衡与容错机制,可以在内网替代F5等硬件负载均衡,降低成本,减少单点
- 服务自动注册与发现
6、zookeeper功能?场景?
功能:数据发布与订阅(配置中心)——dubbo、分布式锁——订单、支付等业务操作、命名服务——dubbo
7、redis与mongodb的比较:
(1)查询:mongodb有丰富的查询语言,redis只能适用于单一查询
(2)场景:mongodb可以应用在海量数据上,而redis数据量更小的操作和运算上
(3)存储方式:mongodb是文档性数据库,redis是key-value键值对数据库
8、zookeeper能够取代nginx吗?
不能。nginx与zookeepr各自功能很广,只是在集群上有交集而已。
9、分布式锁概念?实现方式?
(1)概念:
- 相对于线程锁,方法或代码块加锁,多线程只能允许有一个线程访问。相对于进程锁,给共享资源加锁,同一个操作系统多个进程只能有一个进程访问某共享资源。分布式锁,必须依赖第三方存储介质存储锁的元数据信息,如唯一标识,即锁ID。
- 进程A想访问某数据时,先去第三方查询有无锁ID,如果不存在,则将该锁ID写入,操作该数据。如果存在,说明该数据有其它进程在操作(该进程操作完后会删除锁),进程A会轮偱等待,直到上个进程操作完毕删除锁,才会有操作数据的控制权。
(2)实现方式:
- redis的分布式锁,比如分布式下实现秒杀,可以实现不同服务器下,只有一个进程对某数据有控制权,防止数据脏读
- zookeeper的分布式锁,实际中未使用过,以redis为例进行理解
- mysql的分布式锁,数据增加一个版本标识,更新时+1。提交数据时,将版本号与数据库中对应记录当前版本进行比对,如果大于当前版本,则予以更新,否则认为是过期数据
- 注意:使用redis,会有一些问题,虽然有替代方案可以解决,但推荐使用zookeeper**
10、使用spring的aop概念?哪些应用?原理?
(1)概念:切面,通知(哪些功能,比如日志、redis分布式锁、安全校验)与切入点(具体哪些方法),哪些类中的哪些方法要用到事务功能
(2)应用:日志、事物、安全校验、redis锁等
(3)原理:利用sping创建目标接口实现类,实现诸如事物、日志等相关功能,先执行其对应方法,再执行目标中方法
11、IM相关概念:
(1)XMPP(HTTP):数据传输(应用层)协议,它的过程就如同“解包装--〉包装”的过程
(2)TCP/IP:传输层协议
(3)io socket与nio socket:传统io与nio的主要区别是nio不要一直阻塞着,一旦有消息过来会主动告诉客户端,另一个是nio一个单线程可以处理N个客户端
(4)socket与tcp:通常情况下socket连接就是tcp连接,tcp是传输层协议,socket是tcp协议的具体实现
(5)socket与http:http是建立在tcp(socket)上的一种应用
(6)I/O性能分析:避免大量写,及I/O相关配置解决
(7)mysql通信协议:tcp
(8)XMPP 将复杂性从客户端转移到服务器端。这使得客户端编写变得非常容易,更新系统功能也同样变得容易。XMPP 客户端与服务端通过XML 在TCP 套接字的5222 端口进行通信,而不需要客户端之间直接进行通信
12、voip相关概念?
(1)VOIP技术:包含SIP与H.323在内的共四种协议
(2)H.323与SIP的区别:前者为电话信令模式,较早的一种电话会议功能的协议,目前比较完善,但不易扩展;后者为C/S消息机制,易完善,但正在发展中
(3)IMS核心网:全网IP化。IMS是基于IP的网络控制系统,用于控制电信核心网络,IMS是电路交换核心网的演进
(4)QOS(服务质量)
13、分布式事务概念?实现方式?
(1)概念:一次大的操作下有不同的小的操作,而这些小的操作位于不同的服务器上,且属于不同的应用,分布式事务要保证这些操作要么全部成功,要么全部失败。目的是最终为了确保数据的一致性。事务的acid特性:原子性、一致性、隔离性、持久性
(2)实现方式:
- 基于xa协议的两阶段提交,包含准备阶段与提交阶段。java有支持该方式的jta,可直接配置
- 消息通知,大体思路是,如将某业务操作分为三个步骤,各步骤利用通知来判断其操作状态,并做出相应的操作
- TCC编程模式:将整个业务分为三步骤:Try(调用第三方接口扣钱、本地交易扣钱、记录流水状态)、Confirm(更新流水状态为成功)、Cancel(本地交易恢复、更新流水状态为失败)
基础部分
1、jdk8的主要新特性?
(1)lambda表达式,-> :: 等
(2)函数式编程,如foreach输出
(3)Stream函数式操作流元素集合。遍历集合的高级迭代器
(4)接口中新增default方法(为了满足集合类的编程式函数需求,必须有default方法)、静态方法
(5)最新的time/date api
(6)新增base64加解密api
(7)数组操作改进,同Stream集合高级迭代器
2、线程池Executor作用?wxis的任务队列与工作队列?
(1)作用:
- 减少创建与销毁线程次数,每个工作线程都可以被复用
- 核心参数:corePoolSize、maxNumPoolSize。当创建的线程数等于corePoolSize时,会加入设置的阻塞队列。当队列满了的时候,才会去创建线程任务直至线程池中的数量等于maxNumPoolSize
- 但值得注意的是,我们只需要把实现了Runnable的对象实例放入线程池中,线程池就会自动维护线程的启动、运行、销毁,我们不需要自行调用start方法。
(2)wxis的任务与工作队列,实现方式类似线程池
- 任务队列:监听数据队列(如redis缓存队列)中任务,有任务则按照线程池中规则将任务取出,并传递到工作队列中(可以同时传递给多个不同的工作队列并行进行处理)
- 工作队列:监听任务队列中任务,收到任务队列传递的任务,执行业务方法
3、sleep() 和 wait() 有什么区别?
sleep是Thread类的方法,wait是Object的方法。Sleep暂停后到了指定时间会自动恢复执行,而wait暂停后,只能对该对象发出notify或notifyAll方法才能将其唤醒。调用sleep会释放对象锁,而调用wait不会释放对象锁。
4、多线程有几种实现方式且如何启动?线程有哪些状态?线程同步有几种实现方式?
(1)多线程有两种实现方式,一是实现Runnable接口,实现run方法,用new Thread(Runnable target).start()方法来启动。二是继承Thread类,重写run方法,用start方法启动线程
(2)初始状态、就绪状态、阻塞状态、运行状态、死亡状态
(3)当多个线程同时访问一个变量,并且要对它进行修改时,就需要用到线程同步。synchronized关键字(保证原子性与有序性);volatile(每次都从寄存器中而非内存中获取数据,保证原子性,不保证有序性);使用重入锁(ReentrantLock类,保证原子性与有序性)
5、Thread与Runnable的区别?
(1)Runnable是接口,Thread是类,且实现了Runnable接口。
(2)实现Runnable接口,可以继承多个接口。继承了Thread类就不允许多继承
(3)Runnable可以很方便的实现资料共享,而Thread不太方便,其实也可以
(4)Runnable中没有start方法,只有Thread类中才有
6、启动一个线程是用run()还是start()?
(1)使用start方法,这样才是真正实现了多线程,程序无需等待run方法执行完毕而直接执行其后续的方法。使用start启动线程后,线程处于就绪状态,并没有立即运行,一旦等到cpu时间片,就开始运行run方法。
(2)而使用run方法,则相当于直接运行某对象中某方法,并没有实现多线程
7、面向对象的特征有哪些?
(1)抽象:暂时不关注细节,以便更充分的关注与当前目标有关的方面。类似房屋的架子
(2)继承:子类继承父类的行为。子类可以有父类的方法及属性,也可以重写父类的方法,也可以有自己的方法与属性
(3)多态:不同类的对象,对同一消息作出不同响应。涉及方法重载与方法重写
(4)封装:就是将过程与数据包围起来,对其访问只能通过已定义的界面。
8、overload(方法重载)与override(方法重写)区别?
是多态的两个不同表现。方法重写就是再写一遍,子类对父类的方法重新定义。其方法名、参数位置与个数、返回值均与父类相同。方法重载就是在自己类中再写一个方法,它们具有相同的名字,但有不同的参数位置与个数、返回值。
9、String是基本数据类型吗?
不是。基本数据类型有8个,byte、char、int、short、long、float、double、boolean
10、int与Integer区别?
int是原始数据类型,栈内存。Integer是引用数据类型,堆内存,是java为int提供的封装类。默认值不同,int原始数据类型默认值与其类型有关,而Integer引用数据类型为null。引用类型比较用equals,而原始类型比较用==。
11、String与StringBuffer区别?
都可以对字符串进行存储和操作。只是String操作的是不可变的字符串,重新赋值只是新增了一个对象。而StringBuffer可以对字符串进行增、删、改,不涉及对象新增,因此在内存上还要优于String。
12、byte能否存储一个中文?char能否存储一个中文?
一个中文有两个字节,byte是一个字节,故无法存储一个中文。而char是2个字节,因此存储一个中文没有问题。
13、运行时异常与一般异常区别?
二者都继承自Exception类。运行时异常,通常我们可以选择捕获,也可以不用处理,这类问题通常是由程序逻辑错误引起的,出现这样的异常总是由java虚拟机接管。一般异常表示java编译器强制要求try并catch的异常,否则程序不能通过编译。
14、error与exception区别?
二者的父类都是Throwable类。error一般表示与虚拟机相关的问题,如内存溢出、系统崩溃,一般别指望程序能解决这些问题,应该立即停止程序运行。exception一般表示程序可以处理的异常,可以捕获且能恢复,遇到这类异常,应该尽快捕获并处理,不用终止程序。
15、java中的几种集合的区别?
(1)java中的集合类包括List、Set、Map三大类,它们都处于java.util包中,都是接口,都有自己的实现类。
(2)Set的主要实现类有HashSet、TreeSet。Set中对象是无序的,但TreeSet是有序的,也可以通过实现Comparator类进行自定义排序。元素不能重复,可以使用iterator方法判断重复与否。
(3)List的主要实现类有ArrayList、LinkedList。其中的对象按照索引位置排序,可以有重复对象,允许按照索引检索对象。
(4)Map的主要实现有HashMap、TreeMap。每一个元素包含一个key-value键值对,成对出现。键对象不能重复,值对象可以重复。
16、Collection与Collections区别?
(1)Collection是集合类的上级接口,继承它的接口有Set与List。Set
(2)Collections是集合类的一个帮助类,提供一系列静态方法对集合类进行检索、排序、安全方面的操作等。
17、ArrayList、Vector、LinkedList的存储性能与特性?
(1)ArrayList与Vector都是以数组方式存储的,此数组元素大于实际存储的数据以便更好的增加元素,插入数据要涉及元素移动等内存操作,ArrayList默认增长原来的一半,而Vector默认增长原来的一倍。它们都允许直接按序号索引元素,所以查询数据快而插入数据慢。Vector由于使用了synchornised方法(线程安全),所以通常性能上较ArrayList要差。
(2)LinkedList采用双向链表方式存储,查询数据时需要前向或后向遍历数据,但是插入数据只需要记录本项的前后项即可,因此插入速度比较快
18、HashTable与HashMap的区别?
HashTable是线程安全的,是同步的。而HashMap是非线程安全的,非同步的,但性能方面要比HashTable高。HashMap允许null作为key-value键值对,而HashTable不允许。HashTable有一个contains(包含)方法,而HashMap没有。
19、final、finally、finalize区别?
final用于声明属性、方法和类。表示属性不可变,方法不可覆盖,类不可继承。finnally是异常处理语句结构的一部分,表示总是执行。finalize是Object类的一个方法,在垃圾回收时会调用回收对象的该方法。
20、同步与异步的区别?
同步是指所有操作都做完,才返回结果给用户。异步是指不用等所有操作都做完,马上返回结果给用户。
21、接口与抽象类的区别?
抽象类中允许有一些默认实现的方法,但接口不允许,方法全部为抽象(限jdk1.7前)。抽象类中的变量可以是各种类型的,但接口中的变量必须是public static final型的。抽象类中可以有静态块及静态方法,而接口中不允许(限jdk1.7前)。一个类只能继承一个抽象类,而一个类可以实现多个接口。
22、java栈与堆的区别?
(1)栈是一种线性集合,主要存储值类型数据与句柄,句柄指向的是堆,按照先进后出的方式进行处理。
(2)堆主要存储new的对象,按照先进先出的方式进行处理。
(3)垃圾回收的时候回收的是堆,栈比较难回收,一般不回收。
23、直接请求转发(Forward)与重定向(Redirect)区别?
(1)Forward是指服务器直接访问目标地址的url,并将访问的数据读取再发送给浏览器,浏览器根本不知道响应是从哪里来的,所以浏览器中的url还是之前那个。由于在整个定向的过程中使用的是同一个request,因为request未失效。
(2)Redirect是指服务端返回一个url给浏览器,然后浏览器会重新发一次请求到新的url里面,因此浏览器中的url会发生变化。效率上低于forward。
24、数据连接池的工作机制?
J2ee启动的时候会创建一定数量的池连接,会一直维护不少于此数量的连接。客户端需要连接时,池驱动连接会返回一个未使用的连接,并标示为忙。如果当前没有空闲的连接,池驱动连接就会新建一定数量的连接,新建的连接根据配置而定。当使用的连接调用完成后,池驱动连接将些标记为空闲,其它请求就可以继续使用这个连接。
25、什么是hashcode?它的作用是什么?
(1)java的hashcode就是根据一定的规则,将与对象相关的信息(比如对象的存储地址、对象的字段等)映射成一个数值,这个数值称之为散列值。但是,如果两个不同的对象的hashcode相同,这种情况称之为哈希冲突。
(2)hashcode的主要作用是为了配合基于散列的集合一起运行,这样的集合包括hashtable、hashset和hashmap。主要是用于快速检索元素,减少元素中比较的次数。
26、hashcode与equals区别?
(1)hashcode主要用于快速检索元素,equals主要用于比较两个对象是否相等
(2)两个对象如果equals返回ture,则两个对象的hashcode值一定相同
(3)两个对象如果equals返回false,则两个对象的hashcode值不一定不同
(4)如果两个对象的hashcode值不同,则两个对象equals一定返回false
(5)如果两个对象的hashcode值相同,则两个对象equals返回的结果未知
(6)在重写对象equals方法的同时,必须重写hashcode方法
27、jvm基本概念?运行区域划分?
(1)概念:jvm是可运行的java代码的假想计算机,包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收、一个堆、一个本地方法栈、方法区。Jvm是运行在操作系统之上的,它与硬件没有直接的交互。
(2)运行区域划分:
- 本地方法栈:与jvm栈所发挥的作用类似。
- jvm栈:局部变量、操作数栈、动态链接、方法出口
- 方法区:用以存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等
- 堆:存储对象实例
28、jvm对象分代内存划分?
从对象分代的角度来讲,主要分为持久代、年轻代、老年代。其中持久代位于非堆区(jvm留给自己用的),年轻代与老年代位于堆区。
(1)年轻代的目标是快速收集掉的生命周期较短的对象。又分为eden区,用于存放新建的对象,from区与to区是求助空间。用于当eden区空间不足时,会将其中还存活的对象复制到from区、from不足时,再从from复制到to区,当to也不足的时候,会复制到老年代
(2)老年代用于存放长寿的对象,在年轻代中经过了n次垃圾回收还依然存活的对象,就会被放到老年代中。如,socket连接、session对象生命周期较长的对象
(3)持久代用于存放jvm内部处理或优化所需的内存、类结构、方法等
29、GC是什么?为什么要有GC?考虑两种回收机制?
(1)GC是垃圾回收的意思
(2)内存处理是程序员最容易忽略的地方,会导致系统的不稳定甚至崩溃。Java提供的GC功能可以自动监测已对象是否已超过作用域而达到自动回收的目的,java语言没有提供程序回收已分配的内存的显示操作方法
(3)回收机制有分代复制垃圾回收、标记垃圾回收、增量垃圾回收
30、jvm加载class文件的原理机制?
(1)Jvm中的类是由ClassLoader和它的子类来实现的,ClassLoader是一个重要的java运行时组件。它负责在运行时查找和装入类文件的类。
(2)类加载的五个过程:加载、验证、准备、解析、初始化
31、查看jvm运行时内存
(1)使用相关命令查看其进程
(2)查看该进程下的线程栈情况
(3)对栈情况进行分析、定位
32、常见设计模式?及理解?
(1)常见的设计模式有工厂模式、单例模式、观察者模式、代理模式等。
(2)工厂模式:定义一个创建对象的接口,让子类决定实例化哪一个类
(3)单例模式:保证一个类的对象的唯一性,如数据库连接类就可以设计成单例
(4)观察者模式:又名发布/订阅模式。定义了对象间一对多的关系,使得每一个对象发生改变时,则每一个依赖其的对象都会得到通知并自动更新。原理与我开发过的IM中的消息发布/订阅功能一样。
33、常见的排序有哪些算法及原理?
(1)直接插入排序:计算一个新元素放在哪里,每次新增一个元素都会和原来的顺序进行重新组合
(2)冒泡排序:每进行一次排序,都可以得到一个最大值
(3)选择排序:每进行一次排序,找出最小值放在开始位置,依此类推
34、什么是java序列化?作用?如何实现?
(1)概念:序列化就是把java对象存储在某一地方(硬盘、网络),也就是将对象内容流化。反序列化就是把二进制数据反序列化成对象
(2)作用:方便传输、存储。如内存中的对象属性保存到一个文件或数据库中;套接字在网络上传输对象;RMI
(3)将要序列化的对象实现Serializable接口
35、RMI与RPC区别?
(1)RMI(远程方法调用),调用的每个接口都需要签名。RPC(远程过程调用),请求是参数集的形式,去主机搜索与之匹配的类和方法执行后,通过网络将结果返回
(2)RMI只适用java,RPC是网络服务协议,与操作系统和语言无关
(3)RMI返回的结果是以java为主的,RPC的结果较为统一
36、常用的数据结构有哪些?
链表、堆栈、二叉树、队列、图、集合
37、索引类型有哪些?
唯一索引、单行索引、非唯一索引、分区索引、聚集索引
38、spring mvc运行原理?
(1)用户发送请求至前端控制器dispatcherservlet
(2)dispatcherservlet收到请求调用handermapping处理映射器
(3)处理器映射器根据配置找到具体的处理器,生成处理器对象及处理拦截器一并返回给dispatcherservlet
(4)dispatcherservlet调用handeradapter处理器适配器。
(5)handeradepter处理器适配器调用具体的contarller后端控制器
(6)contraller执行完毕后返回modelview,handeradpter将contraller的执行结果返回给dispatcherservlet
(7)disptcherservlet将modelview交给视图解析器,视图解析器解析后返回具体view
(8)dispatcherservlet根据view进行渲染
(9)dispatcherservlet响应用户
38、java修饰符?
(1)public:对所有类可见
(2)protected:对同一包内的类与子类可见
(3)default:默认不写。对同一包内的类可见
(4)private:在同一类可见
39、svn主干与分支?
(1)trunk:主干代码。用于新的开发
(2)branch:分支代码。用于解决项目路径中产生的bug
(3)tags:版本标记。测试通过后的版本记录
40、jdk源码基础:
(1)openjdk源码,包含hotspot(java虚拟机)、jdk(工具包)、jaxp(xml处理)等核心目录
(2)hotspot包,包含cpu、os、tools、汇编器接口等核心目录
(3)jdk底层由c++实现,存放于jdk目录下的native
41、mysql存储引擎-mylsam与innodb的区别?
(1)因为mylsam相对于简单,支持的索引多,所以在效率上要优于innodb,如果系统读多写少,对原子性要求低,那么mylsam最好的选择,且mylsam恢复速度快,可直接用备份覆盖恢复
(2)如果系统读少写多的时候,尤其是高并发写的时候,对原子性要求高,innodb就是首选
42、elasticsearch基础?
(1)使用restful风格进行操作
(2)全量同步是指全部将数据同步到es,通常是刚刚建立es,第一次同步时使用。
(3)增量同步是指后续的更新,插入、删除记录同步到es
43、struts2运行原理?
(1)servlet容器启动时加载web.xml,通过核心控制器加载FilterDispatcher加载strurts.xml文件并解析,将解析的信息封装在aciontManager中
(2)客户端发送请求,请求被核心控制器FilterDispatcher拦截
(3)FilterDispatcher通过AactonManeger找到对应的aciontfrom和action中响应的方法,在访问方法前先经过struts2设置的17个拦截器,其中一个拦截器的功能是将请求的数据封装在actionfrom中,然后方法执行
(4)方法处理完毕后返回一个字符串,通过struts.xml配置文件中的 找到响应的请求路径
44、数字签名中,公钥与私钥作用?
(1)公钥加密,私钥解密。场景,由你配使用收付嘉提供的公钥与自己平台的私钥加密参数,收付嘉获取url数字签名后,使用由你配平台提供的公钥进行解密参数,进行相关处理
(2)私钥数字签名,公钥验证。场景,收付嘉使用自己的私钥加密对由你配的响应,由你配收到响应后使用收付嘉提供的公钥验证是否是收付嘉的响应
45、web系统慢如何处理?
(1)通过栈、日志查询哪些方法导致
(2)方法中的哪些程序,比如RPC调用?数据库调用?程序本身问题?
(3)需要依赖RPC的,通过连接操作、加大宽带解决,及确认是否是是未关闭连接导致
(4)数据库层面的,需要具体分析如何调优,网上方案很多
(5)程序中相互调用是否严谨,代码是否规范
(6)nginx方面的判断,网络方面的判断,硬件方面的判断
架构部分
1、分布式架构中restful api版本管理?
(1)参数部分:可以直接跟在url后面,也可以放请求head头部中。
(2)处理部分:可以使用spring mvc的注解实现版本的接收与处理,也可以采取直接解析方式
2、一条sql执行很长的时间,你如何优化?从哪些方面?
(1)查看sql是否涉及联表或子查询,如果有,看看能否进行业务拆分,相关字段冗余或者合并成临时表(业务和算法的优化)
(2)涉及联表的查询,是否能进行分表查询,单表之后的查询进行字段整合
(3)如果上述两种情况否,非要用联表查询,那么就需要对相应的查询条件做索引,加快查询速度
(4)针对大的表进行交易流水分离(如交易流水表)
(5)数据库主从分离、读写分离,降低读写针对同一表的压力,到于主从同步,mysql有自带的组件实现主从同步
(6)SQL执行计划中分析sql语句,分析索引是否用上,分析扫描行数等等
(7)查看sql执行日志,是否有其它方面的问题
3、并发的思路,如5000人同时登录(总体思路:把所有用户请求都尽量往前推):**
(1)客户端(如android、网页)缓存相关内容
(2)使用CDN静态页面相关缓存并在程序中应用
(3)使用apache与nginx的静态页面缓存并在程序中应用
(4)数据库与应用服务器分离
(5)使用高性能的单台应用服务器,进行压力测试,计算单台机器tps处理能力
(6)分布式集群,使用nginx进行负载均衡,dubbo微服务+zk配置中心
(7)数据库相关优化:数据库读写分离;同时结合缓存;表建立索引;分库分表;
(8)程序的相关优化:编程规范,如避免循环中创建对象,流、httpClient操作完毕要释放连接等;某业务中非关键功能,使用异步处理;
(9)还应该考虑到分布式锁与分布式事务的问题
4、代码审查(Review code)?如何进行?常用工具?
(1)通过阅读源代码来检查源码与编码标准的符合性及代码质量的活动
(2)设计,源码是否与架构匹配?规范,通过阅读能否理解代码的目的?功能,是否符合预期?是否有安全缺陷等
(3)使用FindBugs工具
5、如何设计高可用的分布式系统?
(1)减少单点。去单点首先要识别整个系统所有主链路的单点。服务器要考虑以主备或集群模式部署,网络专线要考虑同时使用电信或联通专线,优先使用软负载,硬负载兜底
(2)减少依赖。减少远程服务依赖,减少DNS依赖。DNS依赖可以尝试设置本地host,用工具给所有服务器推进最新的域名映射关系。通过本地缓存或近端服务减少RPC调用
(3)限制循环。避免无限死循环,导致cpu利用率百分百,可以限制for循环的最大次数
(4)控制流量。避免异常流量对应用服务器的影响,可以对指定服务器设置流量限制,如TPS、QPS、QPH(每小时总请求量)QPD(每天总请求量)
(5)精准监控。对cpu利用率、内存、硬盘、宽带、系统调用量要熟悉,并精准的对异常情况进行预警
(6)容量规划。定期对系统容量进行评估,并根据实际情况进行扩容
(7)功能开头。打开或关闭某些新功能,对于上线新增加的功能,应考虑设置开头,有问题随时关闭
(8)设置超时。连接超时和读超时设置,不应过大,应根据实际情况进行设置
(9)重试策略。当调用外部服务异常时可设置重试策略,减少对下游系统的影响
(10)隔离。应用隔离、模块隔离、机房隔离、线程池隔离等。可以按照优先级,对变和不变的方式来隔离应用和模块,不同的业务使用不同的连接池,避免低优先级的任务影响高优先级的任务
(11)异步调用。同步调用改为异步调用,降低或避免远程调用故障或调用超时对系统带来的影响
(12)热点缓存。对热点数据进行缓存,降低RPC的调用。如调用方将数据进行本地缓存,并定时去数据方同步数据
(13)缓存容灾。当数据库不可用时可以读取缓存中的数据,并设置缓存分级,如优先选取本地缓存数据,再读取分布式缓存数据
(14)系统分级。对系统进行分级,如ABC三个等级,高级别系统不依赖于低级别系统,且高级别系统比低级别系统有更高的系统可用率
(15)服务降低。如系统出现反应慢等异常情况时,可以关闭部分功能,以保证核心功能的正常使用
(16)流量蓄洪。当流量陡增时,可以将流量蓄洪,如把请求保存在数据库中。再按照指定的QPS进行泄洪,有效的保护下游系统,也保证的服务的可用性。当调用对方系统缓慢时,可采取自动蓄洪
(17)服务权重。在集群环境中,可自动识别高性能服务器,拒绝调用性能低的服务。如集群中对调用超时的服务器进行权重降低,优先调用权重高的服务器
(18)依赖简化。减少系统之间的依赖,比如通过消息驱动,A只负责写数据,B只负责读取数据,而非B直接调用A。当A不可用时,短时间内不影响B服务的调用
(19)灰度和回滚。发布新功能时只让部分服务器生效,且观察几天再逐步切流,如果出现问题只影响部分用户。出现问题可以快速回滚,或者直接下线灰度的机器
(20)减少远程调用。如先局域网服务,再同城服务,最后是跨城服务。如A调用B,B需要调用C获取相关数据,这时B系统可以把数据缓存起来,并设置数据的保鲜度,减少B对C的依赖。配置中心把注册服务的地址推送到调用方服务的系统本地,参数中心把参数配置信息推送到调用方服务的系统本地,而不是让调用方去远程调用获取相关数据
(21)熔断机制。?增加熔断机制,当监控线上数据出现大幅跌涨时,及时中断,避免对业务造成更大影响。比如有的操作可以慢,但是不能出错,这时就要考虑保存相关信息,适时重新操作
(22)运行时加载模块。即OSGI,我们会把我们的业务变成一个个的模块,要能够动态加载或卸载某个模块,当其中一个遇到问题时,能够快速修复问题
(23)代码扫描。利用代码审查工具,如FindBugs提前对代码进行扫描,识别程序中的BUG,如空指针异常、循环依赖等
(24)自动备份。程序、系统配置、数据定期进行备份。以便出现问题时能快速重新部署
(25)线上压测。系统提供的服务需要提前进行压测,知道该服务能够承受的QPS和TPS,从而做出相应准确的限流
6、如何学习新技术?
(1)如果考虑时间成本,从对应书本、网上教程等系统学习一遍,否则查看相关视频
(2)解决工作中的实际问题,比如并发导致系统变慢,就去研究为什么,瓶颈在哪里,哪个环节出问题了,怎么去优化,在解决问题的过程中,就是对之前系统的知识进行深刻的掌握,及综合的运用
管理部分
1、项目经理应具备最重要的能力是什么?
(1)项目经理应具备最重要的能力是协调沟通能力与组织能力,即能够安排合适的人到合适的位置,制订较完备的项目计划方案,让项目组成员清楚的了解自己的职责、工作量及时间安排,遇到问题能够迅速定位及解决
(2)项目经理不一定要技术最好,需要有较高的情商。但是技术好的项目经理在项目进度推进困难的时候将直到很大的作用
2、给你一个4-6人的team,如何分配与管理?
(1)分配:要对成员非常了解和熟悉,知道他们的知识结构与能力水平。挑选一个技术过硬的人作为我的替补和项目的主力,其它的人结合其特点为其指派具体的任务
(2)管理:会在每周进行全面的任务分配,每人获取一周的大概工作,每天的工作由他自己完成并汇报
3、项目实施中有哪些阶段?最重要的是哪些阶段?
(1)依次为需求分析、系统设计、实现与测试、结项阶段、维护阶段
(2)首先是分析、设计阶段。其次是测试阶段
4、如何评估项目状况随时掌握项目进展?
在项目运行过程,仅靠员工的报告来掌握项目的进度是不够的,原因是很多员工都喜欢报喜不报忧。在项目初期就出现的问题苗头,如果收集不上来,在后期会造成很大的纰漏。应该设法两两“挑刺”,前端与后端相互、开发与测试相互、测试与产品相互等
5、未来的职业规划?
(1)短期内是基本熟悉公司的情况、项目情况、成员情况、公司用到的技术方面,并更好的与自己的所掌握所有技能进入很好的磨合
(2)其次是扎实根基,锻炼自己的能力,在自己岗位上做得更好
(3)除了专业技能,还有职场的其它能力也很重要。总之,会根据未来环境的变化,工作内容的变化,不断调整自己的心态,以适应整个市场的变化
6、如何保证项目开发质量?
(1)项目之初,要制订项目质量管理计划,团队内部指定质量规范标准,
(2)开发过程中,设定里程碑,代码审核,并验证阶段性成果,与产品同步沟通确认质量、需求,控制项目需求,防止项目范围蔓延。质量、成本、进度与各方沟通,围绕共同目标取平衡点
(3)项目收尾,整个项目质量确认,进行项目演示,测试,修复,达到约定的标准
(4)维护期,小的修改可以接受,影响在可控范围内。大的改动,为了确保整个项目的质量,要与各方沟通分期进行