一、架构师的日常职责是什么 ? 总体而言,架构师负责软件领域的顶层设计。架构师需要根据公司的发展,规划企业未来若干年的架构,制定可落地的架构方案,解决技术难题,做技术选型与攻关,落地具体的架构。优秀的架构师既能做架构方案,也能写具体的架构代码。
二、开发工程师和架构师有何区别? 工作重点不同:架构师重点在于前期的架构规划,需要制定可落地的架构方案,结合公司的业务场景、团队的技术水平等因素做技术选型,解决技术难题等等;而开发工程师重点在于具体的落地,特别的, 开发工程师的工作重点落地具体的功能。
能力要求不同:架构师要求比较高,要有架构的广度、深度,需要掌握一系列的架构技术栈,要求有架构实战经验,要有很强的系统分析、系统架构、系统设计的能力。开发工程师主要是要求熟悉基本的技术栈,熟悉相关业务,快速落地产品的相关功能。
三、 如何走上架构之路? 首先要有架构师的思维,对分布式、高并发、高性能、高可用、可扩展、松耦合、高内聚、可复用、系统边界、安全等方面有深刻的理解 。 技术面要广,熟悉架构技术栈,比如:熟悉微服务,缓存,分布式消息中间件,分布式任务中间件,数据层中间件,分布式监控中间件,网关中间件,分布式配置中心等等,并不是所有的技术栈要非常精通,但重要的技术,一定要掌握得非常深 。 注重架构技术实践,这是开发童鞋非常缺失的。建议多和架构师多交流,多落地相关技术的实践,集中火力多实战成长会很快的。理论看100遍,不如实践一遍。 掌握好uml,提升个人系统分析、系统架构、系统设计、画业务架构图、技术架构图、写架构方案等方面的能力 。 从架构思维,架构技术栈,架构职责等角度写好一份架构师的简历,重点突出个人掌握的架构技术栈,重点突出项目的架构亮点,难点 。 在企业内部转架构,或者去别的企业转型架构。架构面试方面多实践,如果没经验,可以让架构师老司机们多模拟面试几轮。 四、业务架构师与基础架构师区别 对于java程序猿而言,架构师分为业务架构师,基础架构师两大类,从高级开发转成业务架构师,难度小,出成绩快。业务架构和基础架构有70%是一样的,那就是都要求有架构能力,剩下的30%是业务架构要求熟练掌握业务,制定架构方案,架构落地,基础架构则是100%要求纯技术。短期而言,看似基础架构更风光,其实不然。业务架构发展前景更好一些,因为35岁以后,拼的是综合能力,不再是纯架构能力。业务架构要求有更好的沟通能力,架构规划,架构落地能力,一定的行业业务背景,甚至管理能力,所以从业务架构更容易做到技术总监或cto。如果一直做基础架构,那么可能是首席架构师。一般的架构老司机是业务架构,基础架构通吃的,好就业,到什么山唱什么歌。
五、 UML对系统架构重不重要? UML是架构基本功,但又容易被开发童鞋忽视。架构师要有很强的系统分析,系统架构,系统设计,架构表达能力,通过掌握UML,提高这些能力。业务架构师 通过 UML可以抽象出业务平台的核心用例,可以把复杂的业务流程以分析模型表达清楚,高阶设计阶段,利用包图,组件图,部署图把设计,部署表达清楚。基础架构师设计中间件,可以画uml协作图,或活动图表达技术功能的流程,设计阶段,可以画包图,表达各个包的功能,然后多人可以一起撸技术中间件的具体代码,做具体架构落地。
六、Springcloud和Dubbo用哪个? Dubbo相对而言,成熟稳定,文档齐全门槛低一些,但是很多服务治理方面的功能是缺失的。Springcloud大而全,但很多功能不强大,不成熟。长期而言,个人更看好Spring cloud,虽然目前还有一些坑,而且门槛也比Dubbo高,但整体发展趋势比Dubbo强,Spring cloud生态体系比Dubbo更好,功能更全面。掌握Dubbo和Spring cloud是不冲突的,二者有很多相同的地方,又有很多地方不同。
七、分布式定时任务和一般的任务都什么区别? 分布式定时任务一般是多台服务器可以同时跑定时任务,效率要比一般的任务高,可用性要比一般的任务高(可以做失效转移,架构上没有单点问题,任务节点可以监控),性能要比一般任务的强(架构是强伸缩性,多台机器一起运行,执行时间要短),支持的并发能力远远超过一般的任务(多台机器执行,可以把海量数据分配给不同的机器执行,并发能力非常好)。
八、高并发和高性能的区别和联系是什么? 简单而言,高并发是访问数量,高性能是访问响应时间,两个不同的角度。并发量化的常见参数指标,qps,tps等等,性能量化指标一般是处理时间,比如:接口响应时间是10ms和5分钟,性能是完全不一样的。qps为100和qps为50万的并发架构完全不一样。如果架构不合理,并发量越大,性能越差。如果架构合理,并发量的大小对性能基本没影响,加机器即可,软件架构不需要任何改变。
九、为啥项目经理在国内其实是很危险的职业? 项目管理其实没啥含金量,项目经理工作替代性其实很强,可以被产品经理,技术经理,核心开发等干系人替代。特别是到中年以后,项目经理很难找到合适的工作。
十、reactor线程指的是reactor模型中的哪个部分? 这个问题本身是有问题的。reactor线程模型分为单线程,多线程,主从多线程。实际编程过程中,第二种用的是最多的,
十一、消息中间件目前使用频率最大是RabbitMQ吗? 技术选型是从技术的使用场景,优缺点等方面综合评估的。很多企业用RocketMQ和kafka,大数据基本100%选kafka.
十二、 服务限流有哪些算法? 服务限流常见算法有并发计数器算法,漏桶算法,令牌桶算法。前两种算法不支持突发流量的限流,令牌桶算法支持突发流量的限流。一般用谷歌guava落地令牌桶算法,用sentinel作为服务限流的中间件。
十三、 数据同步有哪些方式 ? 这个问题其实涉及到很多场景的。如果是数据库方面的,可以用SqlLoader、GoldenGate等相关工具同步数据;大数据方面的,可以用ETL、Hadoop等相关技术同步数据;如果是定时调度发起的,可以考虑用SpringBatch,Quartz,Elastic-Job等分布式任务中间件发起同步数据;如果是异步的场景,可以用mq来实现监听并且同步增量数据。大批量的数据情况下,尽可能地考虑用mq、线程池、多线程、数据批量操作等相关技术手段提升性能。
十四、上亿数据如何大规模更新 ? 可以用分布式任务调度中间件的大任务分片来做,把上亿的数据分给多台机器来做。 如果实时性要求不高,完全可以设置一定的时间间隔,减少DB压力;如果实时要求高,数据层需要分库。如果每天增量数据较多,可以考虑周期性地做数据归档。
十五、dubbo是否有什么缺陷 dubbo缺陷很多呀,特别是服务治理方面,服务限流算法有缺陷,突发流量有问题的,服务熔断才刚刚有,但也有缺陷,监控方面只支持点到点的监控,不能做到分布式链路监控,没有服务网关,服务分组能力太弱。dubbo性能还有提升的空间,编解码不支持messagpack,通信方式有待改进。监控中心功能太简单,监控中心和管理后台没有整合。dubbo才刚刚和springcloud打通,支持还不是很友好。
十六、在分布式环境下,如何防止RocketMQ消息重复消费? 消费方可以基于分布式锁来解决rocketmq的消息幂等性的问题。用分布式锁可以从纯技术角度messageid,或者业务角度业务主键唯一性都可以实现rocketmq消息消费的幂等性。另外,rocketmq生产方发送消息,本身就保证了消息的幂等性,主要是消费方消费消息要保证幂等性。
十七、MongoDB和Redis有什么区别? 定位不一样,前者是基于分布式文件存储的数据库,后者是缓存,很多公司是禁止把redis当数据库来使用的,一般而言,有经验的架构团队会规定把缓存失效时间至多设置为7天。超过7天,再重新生成热点数据。
十八、rocketmq是否会丢消息 rocketmq一般是不会丢消息,所谓的rocketmq丢消息,有两种常见的原因,1、开发童鞋写的消费者代码逻辑有bug,比如,消费消息的代码逻辑有异常,却把异常吃掉了,且返回成功的状态,人为的导致丢消息。2、运维层面有问题,把消息写到分布式存储有问题,导致丢消息。这两种情况导致所谓的丢消息,以第一种居多,有不少开发童鞋会犯第一种错误。
十九、Spring cloud 和dubbo用哪个? dubbo相对而言,成熟稳定,文档齐全门槛低一些,但是很多服务治理方面的功能是缺失的。spring cloud大而全,但很多功能不强大,不成熟。长期而言,个人更看好spring cloud,虽然目前还有一些坑,而且门槛也比dubbo高,但整体发展趋势比dubbo强,spring cloud生态体系比dubbo更好,功能更全面。掌握dubbo和spring cloud是不冲突的,二者有很多相同的地方,又有很多地方不同。并且阿里技术团队开发了spring-cloud-alibaba,为dubbo向spring-cloud靠拢,整合做了技术准备。
二十、如何做技术选型? 技术选型是个能力活儿,架构师经常做技术选型,会出有答案的选择题,有几种方案,给到技术高管或者开发团队。而不是一上来就是写架构代码。失职的架构师是给技术领导或者技术团队出问答题,长期出问答题,基本可以走人了。架构师要有一定的架构功力,会给领导或技术团队出选择题,总有一款技术适合的,比较每一种技术(方案)的优缺点,技术领导或者技术团队会很喜欢的,以技服人。架构思路一般是 : 问题(背景)--》技术调研(选型)---》规划(方案)---》落地(撸代码),任何架构或者技术,都要解决问题的,要有价值。
二十一、那技术选型主要是谁来负责,谁来背锅呢? 谁选谁负责,比如,如果是架构师选的,架构师肯定要负责。技术选型,要从公司的业务场景,技术多方面去比较每一种技术的优缺点,比如,对于几种MQ,kafka,rocketmq,rabbitmq,activemq,从技术适用场景,技术的成熟度,技术门槛,可维护性,性能,并发,扩展性等角度去比较每一种MQ技术在以上多个角度的优缺点,做选型的人,尽量做选择题,比较每一种技术的优缺点,做到以技服人,让相关人或相关团队,心服口服。
二十二、如何走上架构之路? 1、首先要有架构师的思维,对分布式、高并发、高性能、高可用、可扩展、松耦合、高内聚、可复用、系统边界、安全等方面有深刻的理解 2、技术面要广,熟悉架构技术栈,比如:熟悉微服务,缓存,分布式消息中间件,分布式任务中间件,数据层中间件,分布式监控中间件,网关中间件,分布式配置中心等等,并不是所有的技术栈要非常精通,但重要的技术,一定要掌握得非常深 3、注重架构技术实践,这是开发童鞋非常缺失的。建议多和架构师多交流,多落地相关技术的实践,集中火力多实战成长会很快的。理论看100遍,不如实践一遍。4、掌握好uml,提升个人系统分析、系统架构、系统设计、画业务架构图、技术架构图、写架构方案等方面的能力 5、从架构思维,架构技术栈,架构职责等角度写好一份架构师的简历,重点突出个人掌握的架构技术栈,重点突出项目的架构亮点,难点 6、在企业内部转架构,或者去别的企业转型架构。架构面试方面多实践,如果没经验,可以让架构师老司机们多模拟面试几轮。
二十三、领域驱动模型平时设计的时候用不用? 不建议用,特别不适合互联网企业。领悟驱动设计是老美发明的一套设计方法论,针对复杂的业务,进行代码分层,不建议用,门槛很高,个人认为不太适合国内的国情,特别不适合互联网的敏捷开发,它对开发人员的素质要求很高。贫血模型,充血模型,失血模型,胀血模型这些模型很复杂、很绕,领悟驱动设计会把代码分层做的比较复杂,开发效率比传统的四层代码分层的效率要低。我以前工作过的一家公司实施过领悟驱动设计,效果差,后来还是改为传统的四层模型。当时有一位架构师同事牵头落地的领域驱动设计的代码分层效果并不好,开发人员落地实际代码有很多困惑,容易产生混乱,开发效率也不高。好的架构是大道至简,简单、易用的架构才有生存空间。
一、数据结构与算法基础 · 说一下几种常见的排序算法和分别的复杂度。 · 用Java写一个冒泡排序算法 · 描述一下链式存储结构。 · 如何遍历一棵二叉树? · 倒排一个LinkedList。 · 用Java写一个递归遍历目录下面的所有文件。 二、Java基础 · 接口与抽象类的区别? · Java中的异常有哪几类?分别怎么使用? · 常用的集合类有哪些?比如List如何排序? · ArrayList和LinkedList内部的实现大致是怎样的?他们之间的区别和优缺点? · 内存溢出是怎么回事?请举一个例子? · ==和equals的区别? · hashCode方法的作用? · NIO是什么?适用于何种场景? · HashMap实现原理,如何保证HashMap的线程安全? · JVM内存结构,为什么需要GC? · NIO模型,select/epoll的区别,多路复用的原理 · Java中一个字符占多少个字节,扩展再问int, long, double占多少字节 · 创建一个类的实例都有哪些办法? · final/finally/finalize的区别? · Session/Cookie的区别? · String/StringBuffer/StringBuilder的区别,扩展再问他们的实现? · Servlet的生命周期? · 如何用Java分配一段连续的1G的内存空间?需要注意些什么? · Java有自己的内存回收机制,但为什么还存在内存泄露的问题呢? · 什么是java序列化,如何实现java序列化?(写一个实例)? · String s = new String("abc");创建了几个 String Object? 三、JVM · JVM堆的基本结构。 · JVM的垃圾算法有哪几种?CMS垃圾回收的基本流程? · JVM有哪些常用启动参数可以调整,描述几个? · 如何查看JVM的内存使用情况? · Java程序是否会内存溢出,内存泄露情况发生?举几个例子。 · 你常用的JVM配置和调优参数都有哪些?分别什么作用? · JVM的内存结构? · 常用的GC策略,什么时候会触发YGC,什么时候触发FGC? 四、多线程/并发 · 如何创建线程?如何保证线程安全? · 如何实现一个线程安全的数据结构 · 如何避免死锁 · Volatile关键字的作用? · HashMap在多线程环境下使用需要注意什么?为什么? · Java程序中启动一个线程是用run还是start? · 什么是守护线程?有什么用? · 什么是死锁?如何避免 · 线程和进程的差别是什么? · Java里面的Threadlocal是怎样实现的? · ConcurrentHashMap的实现原理是? · sleep和wait区别 · notify和notifyAll区别 · volatile关键字的作 · ThreadLocal的作用与实现 · 两个线程如何串行执行 · 上下文切换是什么含义 · 可以运行时kill掉一个线程吗? · 什么是条件锁、读写锁、自旋锁、可重入锁? · 线程池ThreadPoolExecutor的实现原理? 五、Linux使用与问题分析排查 · 使用两种命令创建一个文件? · 硬链接和软链接的区别? · Linux常用命令有哪些? · 怎么看一个Java线程的资源耗用? · Load过高的可能性有哪些? · /etc/hosts文件什么做用? · 如何快速的将一个文本中所有“abc”替换为“xyz”? · 如何在log文件中搜索找出error的日志? · 发现磁盘空间不够,如何快速找出占用空间最大的文件? · Java服务端问题排查(OOM,CPU高,Load高,类冲突) · Java常用问题排查工具及用法(top, iostat, vmstat, sar, tcpdump, jvisualvm, jmap, jconsole) · Thread dump文件如何分析(Runnable,锁,代码栈,操作系统线程ID关联) · 如何查看Java应用的线程信息? 六、框架使用 · 描述一下Hibernate的三个状态? · Spring中Bean的生命周期。 · SpringMVC或Struts处理请求的流程。 · Spring AOP解决了什么问题?怎么实现的? · Spring事务的传播属性是怎么回事?它会影响什么? · Spring中BeanFactory和FactoryBean有什么区别? · Spring框架中IOC的原理是什么? · spring的依赖注入有哪几种方式 · struts工作流程 · 用Spring如何实现一个切面? · Spring 如何实现数据库事务? · Hibernate对一二级缓存的使用,Lazy-Load的理解; · mybatis如何实现批量提交? 七、数据库相关 · MySQL InnoDB、Mysaim的特点? · 乐观锁和悲观锁的区别? · 数据库隔离级别是什么?有什么作用? · MySQL主备同步的基本原理。 · select * from table t where size > 10 group by size order by size的sql语句执行顺序? · 如何优化数据库性能(索引、分库分表、批量操作、分页算法、升级硬盘SSD、业务优化、主从部署) · SQL什么情况下不会使用索引(不包含,不等于,函数) · 一般在什么字段上建索引(过滤数据最多的字段) · 如何从一张表中查出name字段不包含“XYZ”的所有行? · MySQL,B 索引实现,行锁实现,SQL优化 · Redis,RDB和AOF,如何做高可用、集群 · 如何解决高并发减库存问题 · mysql存储引擎中索引的实现机制; · 数据库事务的几种粒度; · 行锁,表锁;乐观锁,悲观锁 八、网络协议和网络编程 · TCP建立连接的过程。 · TCP断开连接的过程。 · 浏览器发生302跳转背后的逻辑? · HTTP协议的交互流程。HTTP和HTTPS的差异,SSL的交互流程? · Rest和Http什么关系?大家都说Rest很轻量,你对Rest风格如何理解? · TCP的滑动窗口协议有什么用?讲讲原理。 · HTTP协议都有哪些方法? · 交换机和路由器的区别? · Socket交互的基本流程? · 协议(报文结构,断点续传,多线程下载,什么是长连接) · tcp协议(建连过程,慢启动,滑动窗口,七层模型) · webservice协议(wsdl/soap格式,与rest协议的区别) · NIO的好处,Netty线程模型,什么是零拷贝 九、Redis等缓存系统/中间件/NoSQL/一致性Hash等 · 列举一个常用的Redis客户端的并发模型。 · HBase如何实现模糊查询? · 列举一个常用的消息中间件,如果消息要保序如何实现? · 如何实现一个Hashtable?你的设计如何考虑Hash冲突?如何优化? · 分布式缓存,一致性hash · LRU算法,slab分配,如何减少内存碎片 · 如何解决缓存单机热点问题 · 什么是布隆过滤器,其实现原理是?False positive指的是? · memcache与redis的区别 · zookeeper有什么功能,选举算法如何进行 · map/reduce过程,如何用map/reduce实现两个数据源的联合统计 十、设计模式与重构 · 你能举例几个常见的设计模式 · 你在设计一个工厂的包的时候会遵循哪些原则? · 你能列举一个使用了Visitor/Decorator模式的开源项目/库吗? · 你在编码时最常用的设计模式有哪些?在什么场景下用? · 如何实现一个单例? · 代理模式(动态代理) · 单例模式(懒汉模式,恶汉模式,并发初始化如何解决,volatile与lock的使用) · JDK源码里面都有些什么让你印象深刻的设计模式使用,举例看看?
算法
1、排序都有哪几种方法?
2、会写常用的排序算法,如快排,归并等。
3、各种排序算法的时间复杂度和稳定性5、和广度优先搜索
6、最小生成树
7、常见Hash算法,哈希的原理和代价
8、全排列、贪心算法、KMP算法、hash算法
9、一致性Hash算法
数据库
1、
2、数据库事务和隔离级别
3、为什么需要锁,锁定分类,锁粒度
4、乐观锁,悲观锁的概念及实现方式5、分页如何实现(Oracle,MySql)
6、Mysql引擎
7、MYSQL语句优化
8、从一张大表读取数据,如何解决性能问题
9、内连接,左连接,右连接作用及区别
10、索引以及索引的实现(B 树介绍、和B树、R树区别
多线程
1、进程和线程的区别
2、并行和并发的区别和联系
3、同步与异步
5、什么叫守护线程
6、如何停止一个线程?
7、什么是线程安全?synchronized和 lock的区别synchronized
8、启动一个线程是用run还是start?
9、wait和sleep的区别
10、notify和notifyAll的区别
11、线程池的作用
12、Java中线程池相关的类
WEB安全
1、什么是SQL注入 ,如何避免。
2、什么是XSS攻击,如何避免
3、什么是CSRF攻击,如何避免
动态代理
1、Java的动态代理的概念
2、Java的动态代理的实现
编码问题
1、常用的字符编码
2、如何解决中文乱码问题
一、String,StringBuffer, StringBuilder 的区别是什么?String为什么是不可变的?
1. String是字符串常量,StringBuffer和StringBuilder是字符串变量。StringBuffer是线程安全的,StringBuilder是非线程安全的。具体来说String是一个不可变的对象,每次修改String对象实际上是创新新对象,并将引用指向新对象。效率很低。StringBuffer
是可变的,即每次修改只是针对其本身,大部分情况下比String效率高,StringBuffer保证同步(synchronized),所以线程安全。StringBuilder没有实现同步,所以非线程安全。但效率应该比StringBuffer高。StringBuffer使用时最好指定容量,这样会比不指定容量快30%-40%,甚至比不指定容量的StringBuilder还快。
二、VECTOR,ARRAYLIST, LINKEDLIST的区别是什么?
vector是同步的,arraylist和linkedlist不是同步的。底层方面,vector与arraylist都是基于object[]array实现的,但考虑vector线程安全,所以arraylist效率上回比vector较快。元素随机访问上,vector与arraylist是基本相同的,时间复杂度是O(1),linkedlist的随机访问元素的复杂度为O(n)。但在插入删除数据上,linkedlist则比arraylist要快很多。linkedlist比arraylist更占内存,因为linkedlist每个节点上还要存储对前后两个节点的引用。
三、HASHTABLE, HASHMAP,TreeMap区别
Hashmap和HashTable都实现了Map接口,但HashTable是线程安全的,HashMap是非线程安全的。HashMap中允许key-value值均为null,但HashTable则不允许。HashMap适合单线程,HashTable适合多线程。HashTAble中的hash数字默认大小是11,增加方式为old*2 1,HashMap中的hash默认大小为16,且均为2的指数。TreeMap则可以将保持的数据根据key值进行排列,可以按照指定的排序方式。默认为升序。
四、ConcurrentHashMap和HashTable的区别
两者均应用于多线程中,但当HashTable增大到一定程度时,其性能会急剧下降。因为迭代时会被锁很长时间。但ConcurrentHashMap则通过引入分割来保证锁的个数不会很大。简而言之就是HashTable会锁住真个map,而ConcurrentHashMap则只需要锁住map的一个部分。
五、Tomcat,apache,jboss的区别
Tomcat是servlet容器,用于解析jsp,servlet。是一个轻量级的高效的容器;缺点是不支持EJB,只能用于Java应用。
Apache是http服务器(web服务器),类似于IIS可以用来建立虚拟站点,编译处理静态页面。支持SSL技术,支持多个虚拟主机等功能。
Jboss是应用服务器,运行EJB的javaee应用服务器,遵循javaee规范,能够提供更多平台的支持和更多集成功能,如数据库连接,JCA等。其对servlet的支持是通过集成其他servlet容器来实现的。如tomcat。
六、GET POST区别
get是从服务器上获取数据,post是向服务器发送数据。
get是把参数数据队列加到提交表单的action属性所指的URL中,值和表单内各个字段一一对应,在url中可以看到。post是通过HTTPpost机制,将表单内各个字段与其内容放置在html header内一起传送到action属性所指的url地址。
对于get方式,服务区端用request.QueryString获取变量值,对于post方式,服务器端用request.Form获取提交的数据。get传送的数据量较小,post较大,一般不受限制。get安全性比post要低,但执行效率较高。
七、SESSION, COOKIE区别
session数据放在服务器上,cookie则放在客户浏览器上。cookie不太安全,因为可以分析出本地cookie,并进行cookie欺骗,考虑安全应使用session。session会在一定时间内保存在服务器上,当访问增多时,会比较占用服务器的性能,考虑减轻服务器压力则应该使用cookie。单个cookie保持的数据不超过4k,很多浏览器都限制要给站点最多保存20个cookie。
八、Servlet的生命周期
主要分三个阶段:初始化——调用init()方法,响应客户请求阶段——调用service()方法,终止阶段——调用destroy方法。工作原理:客户发送一个请求,servlet调用service方法对请求进行响应,即对请求方式进行匹配,选择调用doGet、doPost方法等,然后进入对于的方法中调用逻辑层的方法,实现对客户的响应。自定义的servlet必须首先servlet接口。
具体生命周期包括:装载Servlet、服务器创建Servlet实例、服务器调用Servlet的init()方法、客户请求到达服务器、服务器创建请求对象、服务创建相应对象、服务器激活Servlet的service方法,请求对象和响应对象作为service()方法的参数、service()方法获得关于请求对象的信息,处理请求,访问其他资源,获得需要的信息、service()方法可能激活其他方法以处理请求,如doGet(),doPost()
九、HTTP 报文包含内容
请求方法包括GET,POST,HEAD,PUT,TRACE,OPTIONS,DELETE。请求头如:Host、User-Agent、Connection、Accept-Charset等。请求头部的最后会有一个空行,表示请求头部结束,接下来为请求正文,这一行非常重要,必不可少。请求正文为可选部分,如get就没有。
十、Statement与PreparedStatement的区别,什么是SQL注入,如何防止SQL注入
使用PreparedStatement可以提升代码的可读性和可维护性,可以尽最大可能提高性能。因为Statement每次执行一个SQL命令都会对其编译,但PreparedStatement则只编译一次。PreparedStatement就类似于流水线生产。另一方面PreparedStatement可以极大提高安全性:它对传递过来的参数进行了强制参数类型转换,确保插入或查询数据时,与底层数据库格式匹配。
SQL注入:就是通过将sql命令插入到web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意SQL命令。如sql命令:select id from test where name='1' or 1=1; drop table test,但用PreparedStatement就可以避免这种问题。
十一、redirect, forward区别
redirect:服务器根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址。所以地址栏显示是新的url。forward是指服务器请求资源,直接访问目标地址url,把响应的内容读取过来并再发送给浏览器,浏览器并不知道资源从哪里来,所以地址栏不变。
redirect不能共享数据,forward转发页面和转发到页面可以贡献request中的数据。redirect用于注销,forward用于登陆。forward效率高于redirect。
十二、关于JAVA内存模型,一个对象(两个属性,四个方法)实例化100次,现在内存中的存储状态,几个对象,几个属性,几个方法。
Java新建的对象都放在堆里,如果实例化100次,堆中产生100个对象,一般对象与其属性和方法属于一个整体,但如果属性和方法是静态的,则属性和方法只在内存中存一份。
十三、谈谈Hibernate的理解,一级和二级缓存的作用,在项目中Hibernate都是怎么使用缓存的
一级缓存为session基本的缓存,是内置的不能卸载。一个Session做了一个查询操作,它会把这个结果放在一级缓存中,如果短时间内这个session又做了同一个操作,那么hibernate就直接从一级缓存中获取数据。
二级缓存是SessionFactory的缓存,分为内置缓存和外置缓存两类。即查询结果放在二级缓存中,如果同一个sessionFactory创建的某个session执行了相同的操作,hibernate就会从二级缓存中获取结果。适合放在二级缓存中的数据包括:很少被修改的数据,不是很重要的数据,允许出现偶偶并发的数据,不会被并发访问的数据,参考数据。不适合放在二级缓存中的数据:经常被修改的数据,财务数据,绝对不允许出现并发,与其他应用共享的数据。
十四、反射讲一讲,主要是概念,都在哪需要反射机制,反射的性能,如何优化
能够分析类能力的程序称为反射。反射机制可以用来:在运行中分析类的能力,在运行中查看对象,如编写一个toString方法供所有类使用。实现通用的数据操作代码。利用Method对象,这个对象很像C 的指针。
反射性能优化方法主要为设置不用做安全检查。
十五、谈谈Hibernate与Ibatis的区别,哪个性能会更高一些
Ibatis相当较为简单,容易上手,Hibernate比较复杂,门槛较高。如果系统需要处理数据量很大,性能要求很高,需要执行高度优化的sql语句才能达到性能要求,则此时Ibatis会比较好。
对不同数据库支持方面Hibernate较好,因为Ibatis需要修改的字段较多。另外Hibernate现已成为主流的o/r Mapping框架,开发效率高。
十六、对Spring的理解,项目中都用什么?怎么用的?对IOC、和AOP的理解及实现原理
十七、线程同步,并发操作怎么控制
线程同步不一定就是同时,而是协同步骤,或协同步调。线程同步就是多个线程在逻辑上互有因果关系,所以要对其执行顺序进行协调。
线程并发是指同一时间间隔内,多个线程同时执行。如果线程在时间上能够区分,那么就可以上线程休眠指定的时间来进行同步,可用sleep()方法完成。如果线程在时间上不能区分,但在逻辑顺序上可以区分的话,那么可用jion()方法来完成,一个先执行完,然后执行另一个。如果线程设计较为复杂,那么就只有通过wait(),notify()方法来完成了
十八、描述struts的工作流程。
简略过程就是web应用启动,接收用户请求并进行匹配,返回用户请求信息。
1. 在web应用启动时,加载并初始化ActionServlet,ActionServlet从struct-config.xml文件中读取配置信息,把它们存放到各个配置对象中。
2. 当ActionServlet接收到一个客户请求时,首先检索和用户请求相配的ActionMapping实例,如果不存在,返回用户请求路径无效信息。
3. 如ActionForm实例不存在,则创建一个ActionForm对象,把客户提交的表单数据保存到ActionForm对象中。
4. 根据配置信息决定是否需要表单验证。如果需要验证,就调用ActionForm的Validate()方法。如果Valiedate()方法返回null或返回一个不包含ActionMessage的ActionErrors对象,则表示表单验证成功。
5. ActionServlet更加ActionMapping实例包含的映射信息决定请请求转发给哪个Action。如果相应的Action实例不存在,则先创建这个实例,然后调用Action的execute()方法。
6. Action的execute()方法返回一个ActionForward对象,ActionServlet再把客户请求转发给ActionForward对象指向的JSP组建。
7. ActionForward对象指向的jsp组件生成的动态网页,返回给客户。
十九、Tomcat的session处理,如果让你实现一个tomcatserver,如何实现session机制
当一个session开始时,Servlet容器会创建一个HttpSession对象,在某些情况下把这些HttpSession对象从内存中转移到文件系统中或数据库中。需要访问的时候将它们载入到内存中。这样的好处就是节省内存,当web服务器产生故障时,还可以从文件系统或数据库中恢复Session的数据。管理session有两个类:1)StandardManager,这是一个默认的类,当tomcat启动或重载时将会session对象保存到指定文件中。2)PersistentManager,管理方式更加灵活,具有容错能力,可以及时把Session备份到Session Store中,可以控制内存中Session的数量。
二十、关于Cache(Ehcache,Memcached)
Memcache:分布式内存对象缓存系统,占用其他机子的内存。很多互联网,负载均衡三台(以三台为例)web服务器可以共享一台Memcache的资源。传递的信息以键值对的形式存储。传递的数据要实现序列化。
Oscache:页面级缓存(网上强调最多的东西),占用本机的内存资源。可 以选择缓存到硬盘,如存取到硬盘重启服务也可重新获得上次持久化的资源,而如果缓存到内存就不行。一般没必要缓存到硬盘,因为I/O操作也是比较耗资源,和从数据库取往往优势很小。Oscache存取数据的作用域分为application和session两种。
EhCache:Hibernate缓存,DAO缓存,安全性凭证缓存(Acegi),Web缓存,应用持久化和分布式缓存。EhCache在默认情况下,即在用户未提供自身配置文件ehcache.xml或ehcache-failsafe.xml时,EhCache会依据其自身Jar存档包含的ehcache-failsafe.xml文件所定制的策略来管理缓存。如果用户在classpath下提供了ehcache.xml或ehcache-failsafe.xml文件,那么EhCache将会应用这个文件。如果两个文件同时提供,那么EhCache会使用ehcache.xml文件的配置。
二一、sql的优化相关问题
1. 对查询优化,避免全表扫描
2. 尽量避免where子句中对段进行null值判断,否则将导致引擎放弃使用索引而进行全表扫描。
3. 尽量避免where子句中出现!=或<>,否则将导致引擎放弃使用索引而进行全表扫描。
4. 尽量避免where子句中出现or来连接条件。
5. 慎用in和not in,否则导致全表扫描
6. where中不要用函数操作。
7. Update 语句,如果只更改1、2个字段,不要Update全部字段,否则频繁调用会引起明显的性能消耗,同时带来大量日志。
8. 对于多张大数据量(这里几百条就算大了)的表JOIN,要先分页再JOIN,否则逻辑读会很高,性能很差。
9. 尽可能的使用 varchar/nvarchar 代替 char/nchar,节省空间,提高查询效率
10. select count(*) from table;这样不带任何条件的count会引起全表扫描,并且没有任何业务意义,是一定要杜绝的。
二二、oracle中 rownum与rowid的理解,一千条记录我查200到300的记录怎么查?
二三、如何分析ORACLE的执行计划?
二四、 DB中索引原理,种类,使用索引的好处和问题是什么?
原理:因为检索磁盘比对数据,需要大量的时间和IO,所以就需要构造某列的数据的btree、hash值、位图索引。一般的索引能快速的查找比对,而索引的值记录了磁盘的位置,直接读取数据库字段对应位置的内容。
索引好处:加快数据检索速度、加速表与表之间的连接特别是实现数据的参考完整性方面有特别的意义、减少查询中分组和排序的时间,使用优化隐藏器,提高系统性能。
缺点:创建和维护索引需要时间,索引需要占用物理空间,当对表中的数据惊醒增删改时所有也需要动态维护。
二五、JVM垃圾回收实现原理。垃圾回收的线程优先级。
JVM的堆空间中主要分为年轻代、年老代和永久代。年轻代和年老代是存储动态产生的对象。永久代主要是存储java类信息,包括解析得到的方法属性、字段等等。永久代基本不参与垃圾回收。年轻代分为一个eden区和两个相同的survior区。刚开始创建的对象都放置在eden区。这样主要是为了将生命周期短的对象尽量留在年轻代中。当eden区申请不到空间时,进行minorGC,把存活的对象拷贝到survior。年老代主要存放生命周期比较长的对象,如缓存对象。具体JVM垃圾回收过程如下:
1、对象在Eden区完成内存分配。2、当Eden区满了,在创建对象就会申请不到空间,则触发minorGC,进行young(eden区和1survivor区的垃圾回收)。3、在minorGC时,Eden不能被回收的对象呗放入到空的survior(即Eden肯定被清空),另一个survivor里不能被GC回收的地想也会被放入到这个survivor,始终保证一个survivor是空的。4、当完成第三步的时候、如果发现survivor满了,则这些对象呗copy到old区,或者survivor并没有满,但有些对象已经足够old了,也被放入到old区。当old区北放满之后,进行fullGC。
二六、jvm 最大内存设置。设置的原理。结合垃圾回收讲讲。
JVM内存可以分为堆内存和非堆内存,堆内存给开发人员用的,非堆内存给JVM本身用的,用来存放类型信息,即使GC时也不会释放空间。
堆内存设置:
-Xms 初始堆内存,默认物理内存1/64,也是最小分配堆内存,当空余堆内存小于40%时,会增加到-Xms的最大限制。
-Xmx 最大堆内存分配,默认物理内存1/4,当空余堆内存大于70%时,会减小打-Xms的最小限制。
非堆内存设置:
-XX:PermSize 非堆内存的初始值,默认物理内存的1/64,也是最小非堆内存。
-XX:MaxPermSize 非堆内存最大值,默认物理内存的1/4。
查看堆大小命令为Runtime.getRuntime().maxMemory()。
二七、jvm怎样通过参数调整内存大小
本地环境变量中JVM参数设置:
new一个JAVA_OPTS:
variable name: JAVA_OPTS
variable value: -Xms256M -Xmx512M -XX:PermSize=256M -XX:MaxPermSize=512M
eclipse中参数设置:在缺省VM参数中输入:-Xmx128m -Xms64m -Xmn32m -Xss16m
二八、进程与线程的区别
线程是进程的一个单元,也是进程内的可调度实体。区别就是:1、进程内的线程共享地址空间,进程则自己独立的地址空间。2、进程是资源分配和拥有的单位,同一个进程内的线程共享进程资源。3、线程是处理器调度的基本单位。4、两者均可并发执行。
二九、怎样避免死锁
1. 使用事务时,尽量缩短事务idea逻辑处理过程,及早提交或回滚事务
2. 设置死锁的超时参数为合理范围,如3-10分钟,若超过时间,自动放弃本次操作,避免进程悬挂。
3. 优化程序,检查并避免死锁现象出现。
4. 对所有的脚本和sp都要仔细测试。
5. 所有的sp都要有错误处理。
6. 一般不要修改sql事务的默认级别。不推荐强行加锁。
三十、垃圾回收算法使用的产品、场景
标记-清除算法:标记阶段,确定所有要回收的对象,并标记,清除阶段则将需要回收的对象清除。
复制算法:把内存分为大小相等的两块,每次使用其中的一块,当垃圾回收时,把存活的对象复制到另一块上,然后把这块内存整个清理掉。两块内存比是8:1
标记整理算法:把存活的对象往内存的一端移动,然后直接回收边界以外的内存。标记-整理算法提高了内存的利用率,并且它适合在收集对象存活时间较长的老年代。
分代回收算法:根据对象的存活时间把内存分为新生代和老年代,根据各代对象的存活特点,每代采用不同的GC算法。新生代用标记-复制算法,老年代用标记-整理算法。
如何配置
三一、实际项目中JVM调优
1、JVM启动参数:调整各代的内存比例和垃圾回收算法,提高吞吐量。
2、改进程序逻辑算法,提高性能
3、自定义封装线程池,解决用户响应时间长的问题。比如设置线程最小数量、最大数量
4、连接池
三二、jdk并发包的集合介绍
Map并发包,其实现为ConcurrentHashMap,它实现了ConcurrentMap接口。put方法为根据计算出的hash值去获取segment对象。找到segment对象后调用该对象的put方法完成操作。segment中的put方法则是先加锁,之后判断数组大小,然后觉得是否扩充。然后得到key索要放置的位置。
List并发包,客在高并发环境下使用CopyOnWriteArrayList代替ArrayList。添加元素是利用数组的copy功能和加锁机制。并发情况下,CopyOnWriteArrayList比ArrayList略快了些。
set并发,CopyOnWriteSet和CopyOnWriteArrayList底层实现差不多就是在添加元素时会进行唯一性判断,如果对象数组已经含有重复的元素,不进行增加处理。
queue并发,并发类是ArrayBlockingQueue,底层为数组,并对关键的方法入队、出队操作加入了锁队机制。
Atomic系列类,比如AtomicInteger类,通过使用计数器操作时,一般为了避免线程安全问题,在方法上加锁操作。有了并发包下的原子系列类,我们就可以直接使用。
三三、线程之间的通信
主要包括互斥锁、条件变量、读写锁和线程信号灯。
互斥锁:以排他方式防止数据被并发修改。互斥锁两个状态0和1。具体为申请锁、占用锁以防止数据被修改,此时默认阻塞等等,最后释放锁。
条件变量通信机制:原理,条件变量出现时,可以弥补互斥锁的缺陷,有些问题仅仅依靠互斥锁无法解决。但条件变量不能单独使用,必须配合互斥锁一起实现对资源的互斥访问。
读写锁:在对数据读写时,往往读占主要部分。基本原则是如果其他线程读数据,则允许其他线程执行读操作,但不允许写操作。如果有其他线程申请写操作,则其他线程不能申请读操作和写操作。
线程信号:线程拥有与信号相关的私有数据——线程信号掩码。线程可以向别的线程发送信号,每个线程可以设置自己的阻塞集合。所有线程中,同一信号子任何线程里的对该信号的处理一定相同。
三四、介绍threadlocal
可以叫做线程本地变量或线程本地存储。ThreadLocal为变量在每个线程中都创建了一个副本,每个线程都可以访问自己内部的副本变量。但可能这样做会导致内存占用较大。
ThreadLocal类的几个方法:get() 用来获取ThreadLocal在当前线程中保存的变量副本,set()用来设置当前线程中变量的副本,remove()用来一冲当前线程中的变量副本,initialValue()一般用来在使用时进行重写,是一个延迟加载方法。最常见的ThreadLocal使用场景是用来解决数据库连接、Session管理等。
三五、jdbc的操作过程
加载数据库驱动包、连接数据库、使用sql语句操作数据库、关闭数据库连接
三六、HTTP1.1的新特性
支持持续连接,通过建立一个TCP后,发送请求并得到响应,然后发送更多的请求并得到更多的响应。通过把简历和释放TCP连接的开销分摊到多个请求上,则对每个请求而言,优于TCP而造成的相对开销被大大降低。而且还可以发送流水线请求。
三七、异常处理,包含了什么
参考:http://lavasoft.blog.51cto.com/62575/18920/
三八、堆排序与快速排序
View Code
View Code
堆排序是渐进最优的比较排序算法,达到了O(nlgn)这一下界,而快排有一定的可能性会产生最坏划分,时间复杂度可能为O(n^2)。堆排比较的几乎都不是相邻元素,对cache极不友好。数学复杂度并不一定代表实际运行的复杂度。
三九、Collection有哪些类
Set, List, Map, SortedSet, SortedMap, HashSet, TreeSet, ArrayList, LinkedList, Vector, Collections, Arrays, AbstractCollection
四十、Hashcode总为1会怎样,如何解决hash冲突
当所有对象Hashcode返回都为1时,所有对象都出现hash冲突,其性能会下降
解决hash冲突:
线性再散列法、插入元素时,如果发生冲突,算法会简单的遍历hash表,直到找到表中的下一个空槽,并将该元素放入该槽中。查找元素时,首先散列值所指向的槽,如果没有找到匹配,则继续遍历hash表,直到:(1)找到相应的元素;(2)找到一个空槽(指示查找的元素不存在);(3)整个hash表遍历完毕(指示该元素不存在并且hash表是满的)。
非线性再散列法、线性再散列法是从冲突位置开始,采用一个步长以顺序方式遍历hash表,来查找一个可用的槽,从上面的讨论可以看出,它容易产生聚集现象。非线性再散列法可以避免遍历散列表,它会计算一个新的hash值,并通过它跳转到表中一个完全不同的部分。
外部拉链法、将hash表看作是一个链表数组,表中的每个槽要不为空,要不指向hash到该槽的表项的链表。
四一、如何用两个队列实现栈
即可以将A队列作为栈push,B队列作为栈pop。量队列数据相同。
四二、Object的通用方法
通用方法有equals(), finalize(), toString(), 其他native方法有hashcode(), registerNatives(), getClass(), clone(), notify(), notifyAll(), wait()等。
四三、Java中如何实现多态
多态是OOP中的一个重要特性,主要用来实现动态联编,程序的最终状态只有在执行过程中才被决定而非在编译期间就决定了。有利于提高大型系统的灵活性和扩展性。
多态的三个必要条件:有继承、有方法重写、父类引用指向子类对象。
引用变量的两种类型:编译时类型由申明类型决定,运行时类型由实际对应的对象决定。
View Code
View Code
多态内存:
四四、Java内存泄漏
内存泄漏一般情况下有两种情况:C /C语言中,在堆中分配的内存,没有将其释放掉就删除了所有能访问到这块内存的方式全部删除。(如指针重新赋值)
另一种情况就是在内存对象已经不需要时,还保留这块内存和它的访问方式(引用),由于Java中GC机制,所以Java中的内存泄漏通常指第二种情况。
尽管对于C/C 中的内存泄露情况来说,Java内存泄露导致的破坏性小,除了少数情况会出现程序崩溃的情况外,大多数情况下程序仍然能正常运行。但是,在移动设备对于内存和CPU都有较严格的限制的情况下,Java的内存溢出会导致程序效率低下、占用大量不需要的内存等问题。这将导致整个机器性能变差,严重的也会引起抛出OutOfMemoryError,导致程序崩溃。
在不涉及复杂数据结构情况下,Java内存泄漏表现为一个内存对象的生命周期超出程序需要它的长度。(称为对象游离)。
内存泄漏实例:Java堆溢出、虚拟机栈和本地方法栈溢出、方法区和运行时常量池溢出、本机直接内存溢出
四五、final字段总结
1. final类不能被继承,其中的方法也是默认final类型,没有子类。
2. final方法不能被子类覆盖,但可以继承
3. final变量表示常量,只能被赋值一次赋值后不改变
4. final不能用于构造方法
四六、override(重写)和overload(重载)区别
override:子类在继承父类时,子类可以定义某些方法与父类的方法名称、参数个数、类型、顺序、返回值类型一致,但调用时自动调用子类的方法,父类相当于被覆盖了。
overload:可以表现在类的多态上,函数名相同,但其他参数个数、类型、顺序、返回值等都不相同。
四七、static初始化
未经初始化的全局静态变量会被自动初始化为0。
1、具有1-5工作经验的,面对目前流行的技术不知从何下手,
需要突破技术瓶颈的可以加。
2、在公司待久了,过得很安逸,
但跳槽时面试碰壁。
需要在短时间内进修、跳槽拿高薪的可以加。
3、如果没有工作经验,但基础非常扎实,对java工作机制,
常用设计思想,常用java开发框架掌握熟练的,可以加。
4、觉得自己很牛B,一般需求都能搞定。
但是所学的知识点没有系统化,很难在技术领域继续突破的可以加。
5. 群号:高级架构群 Java进阶群:180705916.备注好信息!送架构视频。
6.阿里Java高级大牛直播讲解知识点,分享知识,
多年工作经验的梳理和总结,带着大家全面、
科学地建立自己的技术体系和技术认知!
架构师面试和被面试经验,总结三条最核心的架构师面试技巧,分别是原理、引导和自圆其说。
- 原理
对于面试而言,原理是关键。在现实开发过程中,我们用到的是实践技能,但面试则完全不一样。很多实践技能很难通过面试的方式展现出来,大多数公司面试的内容会比较偏向与理论和原理分析,这点在大型公司的面试过程中表现的尤为明显。实际上,当你进入很多大型公司之后,你会发现你所具备的实践技能是足够应对工作内容的,但前提是你能够进得去这些公司,这就需要我们从原理性的内容入手把握各项知识体系、工具和框架的本质。
- 引导
面试是一个互动的过程,架构师在面试过程中千万不能演变成单向的、被动应答式的过程,这就需要架构师有一定的引导技巧。当面试官抛出问题时,如果有比较明确的回答思路,那就往自己的思路上引导,引导面试官朝自己擅长的领域去发问。如果自己的思路不清晰,则应该尽快切换话题。
- 自圆其说
自圆其说是面试的最终技巧。自圆其说表现在很多方面,首先体现在简历上。对于简历而言,为了突出自身的卖点,做一些包装无可厚非,但切忌把自己都说不清楚的内容放到简历上,这样一旦面试官的风格是按照简历的内容来提问,那么效果只会适得其反。其次,面试的过程是一个高压力、高强度的过程,难免会紧张。如果引导的不好,可能会面对很多自己并不擅长的内容,这个时候我们就要充分发挥在第10篇《论技术体系的相通性》中提到的技术体系相通性,把已经掌握的知识点应用到未知的领域中去,做到自圆其说。
本篇接下来的内容重点是我在阿里、网易、滴滴、蘑菇街、贝贝网等国内大型互联网架构师岗位的面试之后对面试过程进行总结和思考的一些经验,这些面试题包括技术架构和技术管理两大部分。我们对面试题的分析也将包括两个维度,即:
- 关键思路
对于每道面试题而言,我们认为每个架构师都应该有自己的解题思路。同一个知识点、同一个工具或框架在不同公司的问法可能是不一样的,但把握其中的基本原理都是回答问题的切入点。当我们对问题的原理有了明确的认识,就可以梳理自己的思路,也就能达到前面提到的“自圆其说”的面试效果。
- 参考内容
在部分面试题中,我们会给出该面试题与本课程其他文章中所介绍内容的相关性,从而方便读者对本课程做全方位的贯穿性学习。
架构师技术架构面试题分析
1. 微服务架构基本理念和原则,为什么会在团队中使用微服务架构,实行微服务架构过程中碰到的问题及其解决方案。
关键思路
对于微服务架构而言,服务建模、服务拆分和服务集成是基本的设计理念,而 RPC、RESTful、API 网关、分布式配置中心等基础组件以及服务可用性和数据最终一致性等关键要素也是重点内容。至于引入微服务架构的原因和碰到的困难,团队业务发展特点和组织架构、微服务粒度和边界等都是回答该问题的切入点。为了实现微服务架构,我们可以引入 Spring Cloud 等相对完善的技术实现体系,也可以使用 Dubbo 作为我们的基础微服务架构。
参考内容
微服务架构设计是一个非常综合的概念,本课程中的很多内容都可以作为参考,包括第4篇《领域建模——架构设计的第一步(上)》、第5篇《领域建模——架构设计的第一步(下)》、第6篇《RPC——一切架构的基础》、第7篇《分布式服务架构——最核心的架构》和第8篇《微服务——最热门的架构》。
2. RPC 的概念及其包含的核心组件和主流实现技术,如何实现一个自定义的 RPC 框架。
关键思路
该面试题相对容易回答,RPC 是分布式系统的基础,从思路上我们应该理解它是由网络通信、序列化、传输协议、服务调用等组件所构成。同时,对业界主流 RPC 的实现技术也要有足够的了解,如 Alibaba Dubbo、Google gRPC、Facebook Thrift 等。
参考内容
本课程的第6篇《RPC——一切架构的基础》对 RPC 架构做了详细介绍,在第10篇《论技术体系的相通性》中也提交了 RPC 架构在 Hadoop 中的应用。
3. Dubbo 框架的原理和设计架构,涉及协议、内部基础框架、SPI 扩展性原理等。
关键思路
Dubbo 是目前非常流行的分布式服务框架,也是架构师面试的常见内容。对于 Dubbo 而言,从设计原理上,我们需要掌握微内核架构和 SPI 这两项内容,并能够对 Dubbo 整体架构和实现原理做到自圆其说。这些内容相对都比较明确和固定,只要事先做好准备,基本没有问题。
参考内容
本课程中没有对 Dubbo 做专门的讨论,但第6篇《RPC——一切架构的基础》和第7篇《分布式服务架构——最核心的架构》都与 Dubbo 关系密切。读者也可以参考本课程的配套书籍《系统架构设计--程序员向架构师转型之路》,在该书中对 Dubbo 的实现原理有详细的分析。
4. Zookeeper 的用途和主要应用场景,基本结构和组件,Leader 选举的过程和实现算法,分布式锁的实现方案。
关键思路
Zookeeper 的定位是一种分布式协调工具,在分布式系统中应用非常广泛。Zookeeper 基本概念和用法、Zxid、临时节点、Watcher 机制等是常见的面试点。同时,我们也要掌握分布式协调机制、配置管理、分布式锁等具体应用的场景以及实现方式。最后,实现 Leader 选举过程的 Zab 协议以及其中的各个角色和过程也是面试重点。
参考内容
关于 Zookeeper 的基本概念和典型应用可以参考第10篇《论技术体系的相通性》中内容,我们基于技术体系的相通性对 Zookeeper 的应用列举了几个典型场景并给出了示例。
5. NIO、AIO 等相关概念,Reactor 模式的原理,操作系统实现 Reactor 模式的各种技术以及各自的优缺点,Netty 等主流 NIO 框架的基本架构。
关键思路
对于 IO 模型而言,重点要掌握各种 IO 模型基本理论、操作系统多路复用以及 Reactor 模式。这些内容一般也偏向与固定而明确的解法,面试过程相对也比较容易把握。
参考内容
我们在第6篇《RPC——一切架构的基础》中提交了各种 IO 模型。在第10篇《论技术体系的相通性》中稍微提到了 Reactor 模型,关于 Reactor 模型以及其他常见的架构风格和架构模式也可以参考《系统架构设计--程序员向架构师转型之路》。
6. 使用过的消息中间件介绍,涉及 JMS 规范,场景,集群等,主流几种 MOM 如 ActiveMQ、Kafka、RocketMQ 的比较,Zero-Copy 等细节问题。
关键思路
对于消息中间件,我们首先需要明确消息中间件的各项需求,比如 At Least Once、At Most Once、Exactly Once 等消息传递语义以及顺序消费、消费者幂等性等场景性需求。其次,对于主流的几种消息传递规范以及这些规范的基本原理都是面试的常见切入点,JMS 规范和 AMQP 规范是主流的消息中间件规范。最后,针对这些规范,我们也需要了解各种代表性的实现方式以及各个实现方式下的细节。该面试题涉及面可以很广,从“引导”和“自圆其说”的面试技巧上讲,我们重点突破一种消息中间件,这里给出的建议是 Kafka。尽管 Kafka 没有遵循特定的规范,但很多设计理念和思想都是很不错的,比方说默认情况下 Kafka 实现了 At Least Once 的消息传递语义并提供了 High Level Consumer 和 Low Level Consumer 两种消费者,可以通过 Low Level Consumer 手工控制消费 Offset 来实现 Exactly Once。至于 Zero-Copy等细节问题需要大家在平时进行积累。
参考内容
关于消息传递系统可以参考第9篇《消息传递:可解耦的架构》,当然还需要大家参考相关资料做进一步了解。
7. 缓存系统,Memcached 和 Redis 的选型和特性比较,针对 Redis 的业务场景数据结构建模,lazy-expiration 等细节问题。
关键思路
缓存相关的面试题重点在于几个缓存工具的特性和核心用法。比方说 Redis 和 Memcached,这两种工具在数据结构、内部架构和实现原理上存在较大差异,尤其是它们完全不同的分布式架构。这类面试题相对也比较明确,但需要预防一些比较冷门的知识点,比方说题中的用于处理过期键的 lazy-expiration 以及类似于 Gossip 协议这样的分布式集群构建方法。
参考内容
在第10篇中我们提到了 Gossip 协议,而其他关于缓存的讨论可以参考《系统架构设计--程序员向架构师转型之路》。
8. NoSQL 几种模式和代表性实现技术,批量离线数据处理,实时流式数据处理的基本思路。
关键思路
NoSQL 相关内容经常被提起,主要包括 NoSQL 的几种分类以及代表性的实现技术。这块内容和大数据知识体系有较大关联,而像 Elastic Search 这样的垂直化搜索引擎的内容也属于这一范畴。从思路上讲,如果我们碰到以前没有接触过的 NoSQL 工具和框架,可以从集群、分片、复制等 NoSQL 的基本需求和特征出发进行引申。另一方面,NoSQL 与大数据处理关系密切,面试过程中需要架构师对批量处理、流式处理有一定的了解。
参考内容
关于 Redis 和 Memcached 参考上题,其他关于 NoSQL 的更多讨论以及批量处理的方式和工具同样可以参考《系统架构设计--程序员向架构师转型之路》。
9. CAP 理论/BASE 思想的含义以及在分布式系统设计中的具体体现。
关键思路
CAP 理论和 BASE 思想是比较典型的纯理论型面试题,主要考察架构师对分布式设计理论的掌握。这方面的概念和思想相对也比较明确,需要架构师在理解概念的基础上能够用自己的语言和案例对它们进行包装,从而形成自己的方法论。CAP 理论/BASE 思想在应用上主要体现为分布式环境下的数据最终一致性,关于如何实现最终一致性的设计模式也需要有一定的了解,如常见的可靠事件模式、补偿模式、TCC 模式和最大努力通知模式等。
参考内容
关于 CAP 理论和 BASE 思想本课程中没有具体展开,大家可以参考我刚出版的另一本书籍:《向技术管理者转型 : 软件开发人员跨越行业、技术、管理的转型思维与实践》。
10. 高并发场景的应对思路和技术。
关键思路
对于架构设计而言高并发是一个常见问题,一般也有很多可以展开的地方,比方说拆分和服务化、集群、消息队列、缓存、并行化计算等都是合理的解答内容。从解答思路上讲,这个问题的难点在于形成一套比较完整的知识体系,并且能够以自身的经历和实践作为辅助。很多人在面试过程中可能缺少实践和案例,那么就需要在面试之前做比较多的准备工作,确保能够做到“自圆其说”。
参考内容
本课程中的第6篇《RPC——一切架构的基础》、第7篇《分布式服务架构——最核心的架构》、第8篇《微服务——最热门的架构》、第9篇《消息传递——可解耦的架构》和第10篇《论技术体系的相通性》中的内容或多或少都与高并发相关,其他诸如缓存、高性能服务器等内容可以参考《系统架构设计--程序员向架构师转型之路》。
11. 服务高可用性设计思路和实现方案。
关键思路
对于服务提供者而言,如果一旦自身服务发生错误,那么应该快速返回合理的处理结果;对于服务消费者而言,则重点关注不要被服务提供者所产生的错误影响到自身服务的可用性,这是服务高可用性的设计思路。而从实现手段上讲,服务的高可用性可以采用超时和重试、集群容错、服务隔离、服务降级和服务限流等五大策略。如果能够把这些设计思想和实现策略都能理清楚,那这个问题还是比较容易回答的。
参考内容
在第7篇《分布式服务架构——最核心的架构》和第8篇《微服务——最热门的架构》中提到了一部分关于集群方面的内容,而第9篇《消息传递——可解耦的架构》中的消息中间件解耦也是实现服务可用性的一种思路。更多关于服务可用性方面的讨论可参考:《向技术管理者转型 : 软件开发人员跨越行业、技术、管理的转型思维与实践》。
12. HTTPS 和 OAuth 协议的特点和工作流程。
关键思路
关于安全性,一般会考察加密、认证、授权等通用安全性技术,其中安全性协议是重点。这里列举了两个主要的安全性协议 HTTPS 和 OAuth,一方面这些协议都需要依赖加密、认证、授权等通用安全性技术,另一方面每个协议有其明显的特征和应用场景,这些特征和应用场景往往是面试时问的比较多的地方。例如对于 HTTPS 协议重点关注该协议的工作流程,而对于 OAuth 协议在关注工作流程的同时还需要明确各种授权方式的运行机制。
参考内容
关于安全性的更多讨论可以参考《系统架构设计--程序员向架构师转型之路》中的相关内容。
13. 列举 Spring Cloud 的核心组件和基本实现原理。
关键思路
Spring Cloud 是微服务架构的代表性实现框架,涉及基础框架 Spring Boot、Spring Cloud Netflix Eureka 与服务治理、Spring Cloud Netflix Ribbon 与负载均衡、Spring Cloud Netflix Hystrix 与服务容错、Spring Cloud Netflix Zuul 与 API 网关、Spring Cloud Config 与配置中心等诸多内容。在面试过程中,面试官的主要切入点还是围绕这些框架的原理进行展开,所以还是需要对服务治理、负载均衡、服务容错、分布式配置等基础性概念有足够的认识,然后再与 Spring Cloud 进行整合。
参考内容
第8篇《微服务——最热门的架构》简要介绍了 Spring Cloud 框架,Spring Cloud 中的很多内容实际上与分布式服务框架都是一致的,所以第6篇《RPC——一切架构的基础》和第7篇《分布式服务架构——最核心的架构》也可以做一定参考。更多内容推荐大家一本书:《Spring Cloud 微服务实战》。我目前也正在写一本关于微服务设计和架构方面的书籍,敬请期待。
架构师技术管理面试题分析
现在越来越多的公司把架构师定位为一名技术管理者,在面试过程中也会抛出很多技术管理方面的话题。由于篇幅有限,关于架构师技术管理方面的内容本课程讨论的不多,但我对这块内容做了非常多的总结和探讨,并出版了新书《向技术管理者转型 : 软件开发人员跨越行业、技术、管理的转型思维与实践》。在本篇中,我们将列举几个典型的技术管理方面的面试题,供大家参考。
1.团队建设方面:如团队规模如何规划,团队成员构成方式,绩效相关工作的开展等。
关键思路
从组织管理角度讲,团队建设属于向下管理的范畴。首先,架构师可以从团队组织结构、工作分析、选择人员、培训人员等角度出发展开这一话题,这是比较容易的一个切入点。其次,需要展现架构师自身的领导力和激励能力,这里面可以提到马斯洛需求层次理论、麦格雷戈的 X-Y 理论、赫茨伯格的双因素理论等主流的激励理论,并结合一定的案例展示自己对团队成员成长和管理上的具体措施。最后,可以结合平时与 HRBP 这边的协作简要介绍绩效管理的要点和实践方法。
参考内容
本课程第12篇《架构师的软能力模型》中提到了部分向下管理的内容,关于向下管理的各个方面的详细讨论请读者参考《向技术管理者转型 : 软件开发人员跨越行业、技术、管理的转型思维与实践》。
2.研发过程管理方面:过程资产建设的含义和实践方式,如何应用工具和流程进行研发知识分享和积累,如何开展 Code Review 和重构等。
关键思路
研发过程体系建设是一个非常大的主题,一方面需要对目前主流的研发过程管理方法论有明确的认识,另一方面对具体如何应用这些方法论要有裁剪的意识。敏捷方法是当下流行的过程方法论,但敏捷中也有很多派系,例如 Scrum 与过程管理、精益与消除浪费、看板方法与流程管理、极限编程与工程实践等。同时,过程管理很大程度上要实施过程改进,那么就需要对传统CMMI中的过程改进以及敏捷中的过程改进都有一定的了解。最后,作为技术管理者通常还需要开展过程资产建设、过程裁剪以及建设符合自身团队的轻量级过程模型。
参考内容
关于研发过程体系建设在第11篇《架构设计中的系统工程》中有一定的介绍,更多关于敏捷方法论、过程改进和过程裁剪等研发过程管理各个方面的讨论请读者参考《向技术管理者转型 : 软件开发人员跨越行业、技术、管理的转型思维与实践》。
3.主流方法论方面:对 Scrum、XP、CMMI、PMP、IPD 等研发过程及其改进模型的认识以及应用情况。
关键思路
主流技术管理方法论包括很多分类,每个分类的关注点有所不同,例如 Scrum 和 XP 属于敏捷方法论,CMMI 是一种过程改进模型,PMP 关注于项目管理,而 IPD 则适合与大型团队的产品研发过程。一般在架构师面试中,这些方法论都不会问的太深,主要还是考察基本的概念,如果在基本概念的基础上能够辅助一些具体的案例那基本上就不会有什么问题。
参考内容
关于各种主流技术管理方法论的讨论请读者参考《向技术管理者转型 : 软件开发人员跨越行业、技术、管理的转型思维与实践》。
4.项目和产品管理方面:项目生命周期管理,项目和产品的规划和演进过程把控,结合主流方法论进行实施过程中的裁剪等。
关键思路
项目管理同样范围很广,针对架构师工作而言,常见的项目管理维度包括需求管理、计划管理、质量管理、风险管理、交付管理等。这些维度一方面可以是考察项目管理的核心理念,另一方面也会与技术因素进行结合。有些维度比较通用,但有些维度还是要体现出架构师自身一定的理解和实践能力,例如交付管理就需要结合具体的工具、框架以及设计合理的工作流程。
参考内容
关于项目管理在第11篇《架构设计中的系统工程》中有一定的介绍,关于项目管理的更多内容请读者参考《向技术管理者转型 : 软件开发人员跨越行业、技术、管理的转型思维与实践》。
5. 个人总结方面:对组织级别的贡献,主导某件事情的过程和体会,个人管理风格、优势劣势分析等。
关键思路
从组织管理角度讲,个人总结属于个人管理的范畴,这也是架构师经常忽略的一个管理维度。个人管理首先体现在个人风格的建设上,可以从 DISC 模型出发探讨如何进行个人分析。更常见的问法是考察架构师处理事情的方式方法,对如何安排事情的优先级、如何进行时间管理、如何开展沟通管理等方面可做进一步展开。
参考内容
关于个人管理在第12篇《架构师的软能力模型》中有一定的介绍,更多关于个人管理的讨论请读者参考《向技术管理者转型 : 软件开发人员跨越行业、技术、管理的转型思维与实践》。
一、数据结构与算法基础 · 说一下几种常见的排序算法和分别的复杂度。 · 用Java写一个冒泡排序算法 · 描述一下链式存储结构。 · 如何遍历一棵二叉树? · 倒排一个LinkedList。 · 用Java写一个递归遍历目录下面的所有文件。 二、Java基础 · 接口与抽象类的区别? · Java中的异常有哪几类?分别怎么使用? · 常用的集合类有哪些?比如List如何排序? · ArrayList和LinkedList内部的实现大致是怎样的?他们之间的区别和优缺点? · 内存溢出是怎么回事?请举一个例子? · ==和equals的区别? · hashCode方法的作用? · NIO是什么?适用于何种场景? · HashMap实现原理,如何保证HashMap的线程安全? · JVM内存结构,为什么需要GC? · NIO模型,select/epoll的区别,多路复用的原理 · Java中一个字符占多少个字节,扩展再问int, long, double占多少字节 · 创建一个类的实例都有哪些办法? · final/finally/finalize的区别? · Session/Cookie的区别? · String/StringBuffer/StringBuilder的区别,扩展再问他们的实现? · Servlet的生命周期? · 如何用Java分配一段连续的1G的内存空间?需要注意些什么? · Java有自己的内存回收机制,但为什么还存在内存泄露的问题呢? · 什么是java序列化,如何实现java序列化?(写一个实例)? · String s = new String("abc");创建了几个 String Object? 三、JVM · JVM堆的基本结构。 · JVM的垃圾算法有哪几种?CMS垃圾回收的基本流程? · JVM有哪些常用启动参数可以调整,描述几个? · 如何查看JVM的内存使用情况? · Java程序是否会内存溢出,内存泄露情况发生?举几个例子。 · 你常用的JVM配置和调优参数都有哪些?分别什么作用? · JVM的内存结构? · 常用的GC策略,什么时候会触发YGC,什么时候触发FGC? 四、多线程/并发 · 如何创建线程?如何保证线程安全? · 如何实现一个线程安全的数据结构 · 如何避免死锁 · Volatile关键字的作用? · HashMap在多线程环境下使用需要注意什么?为什么? · Java程序中启动一个线程是用run还是start? · 什么是守护线程?有什么用? · 什么是死锁?如何避免 · 线程和进程的差别是什么? · Java里面的Threadlocal是怎样实现的? · ConcurrentHashMap的实现原理是? · sleep和wait区别 · notify和notifyAll区别 · volatile关键字的作 · ThreadLocal的作用与实现 · 两个线程如何串行执行 · 上下文切换是什么含义 · 可以运行时kill掉一个线程吗? · 什么是条件锁、读写锁、自旋锁、可重入锁? · 线程池ThreadPoolExecutor的实现原理? 五、Linux使用与问题分析排查 · 使用两种命令创建一个文件? · 硬链接和软链接的区别? · Linux常用命令有哪些? · 怎么看一个Java线程的资源耗用? · Load过高的可能性有哪些? · /etc/hosts文件什么做用? · 如何快速的将一个文本中所有“abc”替换为“xyz”? · 如何在log文件中搜索找出error的日志? · 发现磁盘空间不够,如何快速找出占用空间最大的文件? · Java服务端问题排查(OOM,CPU高,Load高,类冲突) · Java常用问题排查工具及用法(top, iostat, vmstat, sar, tcpdump, jvisualvm, jmap, jconsole) · Thread dump文件如何分析(Runnable,锁,代码栈,操作系统线程ID关联) · 如何查看Java应用的线程信息? 六、框架使用 · 描述一下Hibernate的三个状态? · Spring中Bean的生命周期。 · SpringMVC或Struts处理请求的流程。 · Spring AOP解决了什么问题?怎么实现的? · Spring事务的传播属性是怎么回事?它会影响什么? · Spring中BeanFactory和FactoryBean有什么区别? · Spring框架中IOC的原理是什么? · spring的依赖注入有哪几种方式 · struts工作流程 · 用Spring如何实现一个切面? · Spring 如何实现数据库事务? · Hibernate对一二级缓存的使用,Lazy-Load的理解; · mybatis如何实现批量提交? 七、数据库相关 · MySQL InnoDB、Mysaim的特点? · 乐观锁和悲观锁的区别? · 数据库隔离级别是什么?有什么作用? · MySQL主备同步的基本原理。 · select * from table t where size > 10 group by size order by size的sql语句执行顺序? · 如何优化数据库性能(索引、分库分表、批量操作、分页算法、升级硬盘SSD、业务优化、主从部署) · SQL什么情况下不会使用索引(不包含,不等于,函数) · 一般在什么字段上建索引(过滤数据最多的字段) · 如何从一张表中查出name字段不包含“XYZ”的所有行? · MySQL,B 索引实现,行锁实现,SQL优化 · Redis,RDB和AOF,如何做高可用、集群 · 如何解决高并发减库存问题 · mysql存储引擎中索引的实现机制; · 数据库事务的几种粒度; · 行锁,表锁;乐观锁,悲观锁 八、网络协议和网络编程 · TCP建立连接的过程。 · TCP断开连接的过程。 · 浏览器发生302跳转背后的逻辑? · HTTP协议的交互流程。HTTP和HTTPS的差异,SSL的交互流程? · Rest和Http什么关系?大家都说Rest很轻量,你对Rest风格如何理解? · TCP的滑动窗口协议有什么用?讲讲原理。 · HTTP协议都有哪些方法? · 交换机和路由器的区别? · Socket交互的基本流程? · 协议(报文结构,断点续传,多线程下载,什么是长连接) · tcp协议(建连过程,慢启动,滑动窗口,七层模型) · webservice协议(wsdl/soap格式,与rest协议的区别) · NIO的好处,Netty线程模型,什么是零拷贝 九、Redis等缓存系统/中间件/NoSQL/一致性Hash等 · 列举一个常用的Redis客户端的并发模型。 · HBase如何实现模糊查询? · 列举一个常用的消息中间件,如果消息要保序如何实现? · 如何实现一个Hashtable?你的设计如何考虑Hash冲突?如何优化? · 分布式缓存,一致性hash · LRU算法,slab分配,如何减少内存碎片 · 如何解决缓存单机热点问题 · 什么是布隆过滤器,其实现原理是?False positive指的是? · memcache与redis的区别 · zookeeper有什么功能,选举算法如何进行 · map/reduce过程,如何用map/reduce实现两个数据源的联合统计 十、设计模式与重构 · 你能举例几个常见的设计模式 · 你在设计一个工厂的包的时候会遵循哪些原则? · 你能列举一个使用了Visitor/Decorator模式的开源项目/库吗? · 你在编码时最常用的设计模式有哪些?在什么场景下用? · 如何实现一个单例? · 代理模式(动态代理) · 单例模式(懒汉模式,恶汉模式,并发初始化如何解决,volatile与lock的使用) · JDK源码里面都有些什么让你印象深刻的设计模式使用,举例看看? PS:如果你想成为一名优秀的架构师,工作1-5年依然还在迷惘 或者在工作中遇到瓶颈,想跳槽加薪,面试不过,碰到难题等等一系列问题, 想学Java工程化、高性能及分布式、高性能、性能调优、Spring,MyBatis,Netty,dubbo、围绕项目开发和底层原理结构分析、框架源码解读
一、数据结构与算法基础 · 说一下几种常见的排序算法和分别的复杂度。 · 用Java写一个冒泡排序算法 · 描述一下链式存储结构。 · 如何遍历一棵二叉树? · 倒排一个LinkedList。 · 用Java写一个递归遍历目录下面的所有文件。 二、Java基础 · 接口与抽象类的区别? · Java中的异常有哪几类?分别怎么使用? · 常用的集合类有哪些?比如List如何排序? · ArrayList和LinkedList内部的实现大致是怎样的?他们之间的区别和优缺点? · 内存溢出是怎么回事?请举一个例子? · ==和equals的区别? · hashCode方法的作用? · NIO是什么?适用于何种场景? · HashMap实现原理,如何保证HashMap的线程安全? · JVM内存结构,为什么需要GC? · NIO模型,select/epoll的区别,多路复用的原理 · Java中一个字符占多少个字节,扩展再问int, long, double占多少字节 · 创建一个类的实例都有哪些办法? · final/finally/finalize的区别? · Session/Cookie的区别? · String/StringBuffer/StringBuilder的区别,扩展再问他们的实现? · Servlet的生命周期? · 如何用Java分配一段连续的1G的内存空间?需要注意些什么? · Java有自己的内存回收机制,但为什么还存在内存泄露的问题呢? · 什么是java序列化,如何实现java序列化?(写一个实例)? · String s = new String("abc");创建了几个 String Object? 三、JVM · JVM堆的基本结构。 · JVM的垃圾算法有哪几种?CMS垃圾回收的基本流程? · JVM有哪些常用启动参数可以调整,描述几个? · 如何查看JVM的内存使用情况? · Java程序是否会内存溢出,内存泄露情况发生?举几个例子。 · 你常用的JVM配置和调优参数都有哪些?分别什么作用? · JVM的内存结构? · 常用的GC策略,什么时候会触发YGC,什么时候触发FGC? 四、多线程/并发 · 如何创建线程?如何保证线程安全? · 如何实现一个线程安全的数据结构 · 如何避免死锁 · Volatile关键字的作用? · HashMap在多线程环境下使用需要注意什么?为什么? · Java程序中启动一个线程是用run还是start? · 什么是守护线程?有什么用? · 什么是死锁?如何避免 · 线程和进程的差别是什么? · Java里面的Threadlocal是怎样实现的? · ConcurrentHashMap的实现原理是? · sleep和wait区别 · notify和notifyAll区别 · volatile关键字的作 · ThreadLocal的作用与实现 · 两个线程如何串行执行 · 上下文切换是什么含义 · 可以运行时kill掉一个线程吗? · 什么是条件锁、读写锁、自旋锁、可重入锁? · 线程池ThreadPoolExecutor的实现原理? 五、Linux使用与问题分析排查 · 使用两种命令创建一个文件? · 硬链接和软链接的区别? · Linux常用命令有哪些? · 怎么看一个Java线程的资源耗用? · Load过高的可能性有哪些? · /etc/hosts文件什么做用? · 如何快速的将一个文本中所有“abc”替换为“xyz”? · 如何在log文件中搜索找出error的日志? · 发现磁盘空间不够,如何快速找出占用空间最大的文件? · Java服务端问题排查(OOM,CPU高,Load高,类冲突) · Java常用问题排查工具及用法(top, iostat, vmstat, sar, tcpdump, jvisualvm, jmap, jconsole) · Thread dump文件如何分析(Runnable,锁,代码栈,操作系统线程ID关联) · 如何查看Java应用的线程信息? 六、框架使用 · 描述一下Hibernate的三个状态? · Spring中Bean的生命周期。 · SpringMVC或Struts处理请求的流程。 · Spring AOP解决了什么问题?怎么实现的? · Spring事务的传播属性是怎么回事?它会影响什么? · Spring中BeanFactory和FactoryBean有什么区别? · Spring框架中IOC的原理是什么? · spring的依赖注入有哪几种方式 · struts工作流程 · 用Spring如何实现一个切面? · Spring 如何实现数据库事务? · Hibernate对一二级缓存的使用,Lazy-Load的理解; · mybatis如何实现批量提交? 七、数据库相关 · MySQL InnoDB、Mysaim的特点? · 乐观锁和悲观锁的区别? · 数据库隔离级别是什么?有什么作用? · MySQL主备同步的基本原理。 · select * from table t where size > 10 group by size order by size的sql语句执行顺序? · 如何优化数据库性能(索引、分库分表、批量操作、分页算法、升级硬盘SSD、业务优化、主从部署) · SQL什么情况下不会使用索引(不包含,不等于,函数) · 一般在什么字段上建索引(过滤数据最多的字段) · 如何从一张表中查出name字段不包含“XYZ”的所有行? · MySQL,B 索引实现,行锁实现,SQL优化 · Redis,RDB和AOF,如何做高可用、集群 · 如何解决高并发减库存问题 · mysql存储引擎中索引的实现机制; · 数据库事务的几种粒度; · 行锁,表锁;乐观锁,悲观锁 八、网络协议和网络编程 · TCP建立连接的过程。 · TCP断开连接的过程。 · 浏览器发生302跳转背后的逻辑? · HTTP协议的交互流程。HTTP和HTTPS的差异,SSL的交互流程? · Rest和Http什么关系?大家都说Rest很轻量,你对Rest风格如何理解? · TCP的滑动窗口协议有什么用?讲讲原理。 · HTTP协议都有哪些方法? · 交换机和路由器的区别? · Socket交互的基本流程? · 协议(报文结构,断点续传,多线程下载,什么是长连接) · tcp协议(建连过程,慢启动,滑动窗口,七层模型) · webservice协议(wsdl/soap格式,与rest协议的区别) · NIO的好处,Netty线程模型,什么是零拷贝 九、Redis等缓存系统/中间件/NoSQL/一致性Hash等 · 列举一个常用的Redis客户端的并发模型。 · HBase如何实现模糊查询? · 列举一个常用的消息中间件,如果消息要保序如何实现? · 如何实现一个Hashtable?你的设计如何考虑Hash冲突?如何优化? · 分布式缓存,一致性hash · LRU算法,slab分配,如何减少内存碎片 · 如何解决缓存单机热点问题 · 什么是布隆过滤器,其实现原理是? False positive指的是? · memcache与redis的区别 · zookeeper有什么功能,选举算法如何进行 · map/reduce过程,如何用map/reduce实现两个数据源的联合统计 十、设计模式与重构 · 你能举例几个常见的设计模式 · 你在设计一个工厂的包的时候会遵循哪些原则? · 你能列举一个使用了Visitor/Decorator模式的开源项目/库吗? · 你在编码时最常用的设计模式有哪些?在什么场景下用? · 如何实现一个单例? · 代理模式(动态代理) · 单例模式(懒汉模式,恶汉模式,并发初始化如何解决,volatile与lock的使用) · JDK源码里面都有些什么让你印象深刻的设计模式使用,举例看看?
1、什么是 MyBatis?答:MyBatis 是一个可以自定义 SQL、存储过程和高级映射的持久层框架。2、讲下 MyBatis 的缓存答:MyBatis 的缓存分为一级缓存和二级缓存,一级缓存放在 session 里面,默认就有,二级缓存放在它的命名空间里,默认是不打开的,使用二级缓存属性类需要实现 Serializable 序列化接口(可用来保存对象的状态),可在它的映射文件中配置<cache/>3、Mybatis 是如何进行分页的?分页插件的原理是什么?答:1)Mybatis 使用 RowBounds 对象进行分页,也可以直接编写 sql 实现分页,也可以使用Mybatis 的分页插件。2)分页插件的原理:实现 Mybatis 提供的接口,实现自定义插件,在插件的拦截方法内拦截待执行的 sql,然后重写 sql。举例:select from student,拦截 sql 后重写为:select t. from (select from student)tlimit 0,104、简述 Mybatis 的插件运行原理,以及如何编写一个插件?答:1)Mybatis 仅可以编写针对 ParameterHandler、ResultSetHandler、StatementHandler、Executor 这 4 种接口的插件,Mybatis 通过动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这 4 种接口对象的方法时,就会进入拦截方法,具体就是InvocationHandler 的 invoke()方法,当然,只会拦截那些你指定需要拦截的方法。2)实现 Mybatis 的 Interceptor 接口并复写 intercept()方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,记住,别忘了在配置文件中配置你编写的插件。5、Mybatis 动态 sql 是做什么的?都有哪些动态 sql?能简述一下动态 sql 的执行原理不?答:1)Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能。2)Mybatis 提供了 9 种动态 sql 标签:trim|where|set|foreach|if|choose|when|otherwise|bind。3)其执行原理为,使用 OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接 sql,以此来完成动态 sql 的功能。6、#{}和{}时,就是把{}替换成变量的值。4)使用#{}可以有效的防止 SQL 注入,提高系统安全性。7、为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动的区别在哪里?答:Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而 Mybatis 在查询关联对象或关联集合对象时,需要手动编写 sql 来完成,所以,称之为半自动 ORM 映射工具。8、Mybatis 是否支持延迟加载?如果支持,它的实现原理是什么?答:1)Mybatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载,association指的就是一对一,collection 指的就是一对多查询。在 Mybatis 配置文件中,可以配置是否启用延迟加载 lazyLoadingEnabled=true|false。2)它的原理是,使用 CGLIB 创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用 a.getB().getName(),拦截器 invoke()方法发现 a.getB()是 null 值,那么就会单独发送事先保存好的查询关联 B 对象的 sql,把 B 查询上来,然后调用 a.setB(b),于是 a 的对象 b 属性就有值了,接着完成 a.getB().getName()方法的调用。这就是延迟加载的基本原理。9、MyBatis 与 Hibernate 有哪些不同?答:1)Mybatis 和 hibernate 不同,它不完全是一个 ORM 框架,因为 MyBatis 需要程序员自己编写 Sql 语句,不过 mybatis 可以通过 XML 或注解方式灵活配置要运行的 sql 语句,并将java 对象和 sql 语句映射生成最终执行的 sql,最后将 sql 执行的结果再映射生成 java 对象。2)Mybatis 学习门槛低,简单易学,程序员直接编写原生态 sql,可严格控制 sql 执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是 mybatis 无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套 sql 映射文件,工作量大。3)Hibernate 对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用 hibernate 开发可以节省很多代码,提高效率。但是Hibernate 的缺点是学习门槛高,要精通门槛更高,而且怎么设计 O/R 映射,在性能和对象模型之间如何权衡,以及怎样用好 Hibernate 需要具有很强的经验和能力才行。总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。10、MyBatis 的好处是什么?答:1)MyBatis 把 sql 语句从 Java 源程序中独立出来,放在单独的 XML 文件中编写,给程序的维护带来了很大便利。2)MyBatis 封装了底层 JDBC API 的调用细节,并能自动将结果集转换成 Java Bean 对象,大大简化了 Java 数据库编程的重复工作。3)因为 MyBatis 需要程序员自己去编写 sql 语句,程序员可以结合数据库自身的特点灵活控制 sql 语句,因此能够实现比 Hibernate 等全自动 orm 框架更高的查询效率,能够完成复杂查询。11、简述 Mybatis 的 Xml 映射文件和 Mybatis 内部数据结构之间的映射关系?答:Mybatis 将所有 Xml 配置信息都封装到 All-In-One 重量级对象 Configuration 内部。在Xml 映射文件中,<parameterMap>标签会被解析为 ParameterMap 对象,其每个子元素会被解析为 ParameterMapping 对象。<resultMap>标签会被解析为 ResultMap 对象,其每个子元素会被解析为 ResultMapping 对象。每一个<select>、<insert>、<update>、<delete>标签均会被解析为 MappedStatement 对象,标签内的 sql 会被解析为 BoundSql 对象。12、什么是 MyBatis 的接口绑定,有什么好处?答:接口映射就是在 MyBatis 中任意定义接口,然后把接口里面的方法和 SQL 语句绑定,我们直接调用接口方法就可以,这样比起原来了 SqlSession 提供的方法我们可以有更加灵活的选择和设置.13、接口绑定有几种实现方式,分别是怎么实现的?答:接口绑定有两种实现方式,一种是通过注解绑定,就是在接口的方法上面加上@Select@Update 等注解里面包含 Sql 语句来绑定,另外一种就是通过 xml 里面写 SQL 来绑定,在这种情况下,要指定 xml 映射文件里面的 namespace 必须为接口的全路径名.14、什么情况下用注解绑定,什么情况下用 xml 绑定?答:当 Sql 语句比较简单时候,用注解绑定;当 SQL 语句比较复杂时候,用 xml 绑定,一般用xml 绑定的比较多15、MyBatis 实现一对一有几种方式?具体怎么操作的?答:有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次,通过在 resultMap 里面配置 association 节点配置一对一的类就可以完成;嵌套查询是先查一个表,根据这个表里面的结果的外键 id,去再另外一个表里面查询数据,也是通过 association 配置,但另外一个表的查询通过 select 属性配置。*