关于java开发面试的大致问题方向

时间:2022-10-30 22:11:48


一、Java基础

1. 集合框架
A)集合中泛型优点?


1)HashMap---允许一个键为null,允许多个值为null,默认容量是16,加载因子是0.75f,每次扩容一倍,是一种异步式线程不安全的映射。
2)Hashtable---不允许键值为null,默认初始容量是11,加载因子是0.75f,是一种同步式线程安全的映射(一个Hashtable在同一时间只能被一个线程访问)。
3)ConcurrentHashMap---异步式线程安全的映射(一个线程在同一时间只能访问该Map中的一个键值对,不同线程在同一时间可以访问同一Map的不同键值对)


HashMap, LinkedList, ArrayList底层


手写LingkedList、ArrayList、Quenue、Stack


2. 设计模式
1)单例模式——在全局过程中只存在该类唯一的一个实例。
需要把构造函数私有化,提供一个本类的静态变量,并且通过对应的静态方法来获取这个唯一的静态变量
饿汉式:不存在多线程并发安全问题,可能会导致内存的浪费
懒汉式:相对节省内存,存在线程安全问题
Spring框架中bean的创建默认就是单例的
2)装饰模式---利用一个统一的父类或者接口,将一个子类对象作为参数来构造另一个子类对象,对其中的方法做改变或者增强
3)代理模式
静态代理产生类
动态代理产生对象,
4)工厂模式


3. JDK环境配置


 
Java_home指向java jdk安装目录,通知某些软件如何找到jdk安装目录;
Classpath表示类搜索路径,可以使用点(.);
Path指向jdk的bin目录,java、javac等命令就安装在此目录中


4. 泛型
1. 它提供了编译期的类型安全,确保你只能把正确类型的对象放入集合中, 避免了在运行时出现ClassCastException。
2. 泛型中的限定通配符和非限定通配符
一种是<? extends T>它通过确保类型必须是T的子类来设定类型的上界,另一种是<? super T>它通过确保类型必须是T的父类来设定类型的下界。




5. Tomcat的端口在哪个文件的哪个标签修改?


6. 多线程+死锁+生产消费模型


7. redis基本类型


8. http, tcp等协议


9. 冒泡排序,


10. jdk1.8  1.9新特性
从JDK1.8开始,接口中允许定义实体方法,但是必须使用default修饰;
在接口中也允许定义静态方法;
Lambda表达式:实际上是在重写一个抽象方法;




13. Debug
F5---钻入方法的内;F6---下一步;F7--从方法中跳出继续执行;F8---执行到下一个断点


11. 反射
静态编译:在编译时确定类型,绑定对象。 
动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,可以降低类之间的藕合性。 
 而反射就是运用了动态编译,在程序运行状态中, 通过反射机制,获取类的字节码,对于任意一个类或者对象, 我们都能剖析它,了解它,都能够知道它的所有属性和方法; 都能够调用它的任意一个方法和属性。
例子:factory工厂模式(fruit接口,很多实现类(如苹果类...),如果不用反射,factory会很庞大,用反射,通过传入类名,创建对象)


反射在ssm中的应用:
1)mybatis在进行resultMap或resultType映射时;
2)Spring配置文件中bean的创建
3)SpringMVC拦截器


常用方法:Class.forName("java.util.List"); newInstance(); getMethod();
              getConstructor(); getDeclaredField(String filedName)






二、JVM




三、数据库
1. Sql语句执行顺序:from--where--group by--having--select--order by


2. 数据库事务的四个特性及含义
原子性:整个事务中的所有操作,要么全部完成,要么全部不完成;
一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏;
隔离性:在同一时间仅有一个请求用于同一数据;
持久性:在事务完成后,该事务所对数据库所作的更改便持久的保存在数据库之中


3. sql优化:
对查询进行优化:
A)要尽量避免全表扫描,首先应考虑在 where及 order by 涉及的列上建立索引;但索引不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引
B)尽量避免在where子句中
进行null值判断(最好不要给数据库留null)、
使用!=或<>操作符、
使用模糊查询like、
对字段进行表达式操作或函数操作
这都将导致引擎放弃使用索引而进行全表扫描
C)尽量避免在where子句中使用or来连接查询条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描;可以使用union all来代替or;
D)慎用in和not in,这也会导致全表扫描;对于连续的数值,可以用between代替in;很多时候可以用exists代替in;
E)查询时,用具体的字段代替*


其他:
A)如果只更改1、2个字段,不要Update全部字段,否则频繁调用会引起明显的性能消耗,同时带来大量日志。
B)尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。


4. 数据库索引


创建索引语句: CREATE  [unique]INDEX  索引名 ON 表名 (字段名1,字段名2)
是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索 引的实现通常使用B树及其变种B+树。
常见的有4种索引:
唯一索引:唯一索引是不允许其中任何两行具有相同索引值的索引;
主键索引:数据库表经常有一列或列组合,其值唯一标识表中的每一行,
主键将自动创建主键索引;
聚集索引:索引中键值的逻辑顺序决定了表中相应行的物理顺序;
非聚集索引:索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同。


5. mysql分页查询:
SELECT * FROM student LIMIT (PageNo - 1) * PageSize,PageSize;
Oracle分页:
SELECT * FROM
(SELECT ROWNUM rn ,* FROM student WHERE Rownum <= pageNo * pageSize )
WHERE rn > (pageNo - 1) * pageSize
6. sql存储过程
存储过程就是将常用的或很复杂的工作,预先用SQL语句写好并用一个指定的名称存储起来,可以根据条件执行不同SQL语句,那么以后要叫数据库提供与已定义好的存储过程的功能相同的服务时,只需调用execute,即可自动完成命令。
create proc query_book as select * from book go
--调用存储过程 exec query_book


三、框架
1. 拦截器和过滤器的区别
拦截器是基于Java的反射机制的,而过滤器是基于函数回调。
拦截器不依赖于servlet容器,过滤器依赖与servlet容器。
拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
拦截器可以访问action上下文里的对象,而过滤器不能访问。
拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。


2. Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。


四、rabbitMQ
1. rabbitMQ的5常用工作模式(一共有6中模式):
简单模式:略
工作模式:生产者为消息队列中生产消息,多个消费者争抢执行权利,谁抢到谁执行.如秒 杀业务、抢红包等
发布订阅模式:生产者生产消息,将消息发往交换机,交换机再将消息发往订阅了 当前消息的队列,再次有各个队列的消费者执行(类似于广播)
路由模式:生产者发布消息,会定义指定的路由key(如 key:error),这时交换机会根 据路由key发往满足条件的队列中,如果队列中没有符合条件的路由key将不 能执行该消息.
主题模式:与路由模式相似,key=*xx*


2.rabbitMQ中2个重要端口端口
15672:访问rabbitMQ的控制台; 5672:程序连接rabbitMQ的端口


3. ACK机制(消息确认机制):
如果采用no-ack的方式进行确认(每次Consumer接到数据后,不管是否处理完成,RabbitMQ Server会立即把这个Message标记为完成,然后从queue中删除了),在Consumer处理数据的过程中,Consumer出错了,异常退出了,而数据还没有处理完成,那么数据就丢失了。
  为了保证数据不被丢失,RabbitMQ支持消息确认机制(acknowledgments)。为了保证数据能被正确处理而不仅仅是被Consumer收到,应该在处理完数据后发送ack。如果一个Consumer异常退出了,它处理的数据能够被另外的Consumer处理,这样数据在这种情况下就不会丢失了。在处理数据后发送的ack,就是告诉RabbitMQ数据已经被接收,处理完成,RabbitMQ可以去安全的删除它了。


4.其他几种消息队列:MSMQ、ActiveMQ、ZeroMQ


5.队列持久化:非持久化时,当rabbitmq宕机时,消息是丢失的。持久化时,会将数据写入磁盘,宕机重启后,会恢复这些消息。非持久化信息保存到内存,持久化信息保存到磁盘。


6.AMQP(高级消息队列协议):Spring对AMQP做了支持,目前只是做了RabbitMQ的实现,RabbitMQ是一个开源的AMQP实现


7. rabbitmq的优先级做法 
目前成熟的消息队列产品有很多,著名的例如rabbitmq。它使用起来相对还是比较简单的,功能也相对比较丰富,一般场合下是完全够用的。但是有个很烦人的就是它不支持优先级。
例如一个发邮件的任务,某些特权用户希望它的邮件能够更加及时的发送出去,至少比普通用户要优先对待。默认情况下rabbitmq是无法处理掉的,扔给rabbitmq的任务都是FIFO先进先出。但是我们可以使用一些变通的技巧来支持这些优先级。创建多个队列,并为rabbitmq的消费者设置相应的路由规则。
 我们可以定义一个专门处理高优先级队列的消费者,它空闲的时候也不处理低优先级队列的数据。这类似银行的VIP柜台,普通客户在银行取号排队,一个VIP来了他虽然没有从取号机里拿出一个排在普通会员前面的票,但是他还是可以更快地直接走VIP通道。
8. rabbitMQ中几个重要概念
Broker:简单来说就是消息队列服务器实体。
Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列。
Queue:消息队列载体,每个消息都会被投入到一个或多个队列。
Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来。
Routing Key:路由关键字,exchange根据这个关键字进行消息投递。
vhost:虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离。
producer:消息生产者,就是投递消息的程序。
consumer:消息消费者,就是接受消息的程序。
channel:消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表 一个会话任务。由Exchange,Queue,RoutingKey三个才能决定一个从Exchange到Queue 的唯一的线路。


9. rabbitMQ与activeMQ对比:
A) ActiveMq是Java,RabbitMQ是Erlang(天生具备高并发高可用的erlang 语言),理论上, RabbitMQ的性能比ActiveMq更 强,是非Java系统的首选;
B) RabbitMQ:基于AMQP协议
高级消息队列协议使得遵从该规范的客户端应用和消息中间件服务器的 全功能互操作成为可能。
ActiveMQ:基于STOMP协议(简单(流)文本定向消息协议)
C)两者都支持消息持久化
D)RabbitMQ支持的并发比较高(天生具备高并发高可用的erlang 语言)


五、Solr
1. 正向索引: 先加载文章,再根据文章中的关键字指定相应的位置;
倒排索引(lucene/solr): 先查询索引关键字,之后在返回关键字所在的文章.现阶段主流的检索工具一般都会使用倒排索引.
2. Lucene:是一套用于全文检索和搜寻的开源程式库,采用了词元匹配和切分词。举个例子:java后端工程师,可以分词为:java、工程师、后端等,所以我们搜索的时候都可以检索到。有一种分词器就是IK中文分词器,它有细粒度切分和智能切分,即根据某种智能算法。
Solr:是一个独立企业级搜索应用服务器(采用java5开发),基于Lucene的全文搜索服务器。Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展,并对索引、搜索性能进行了优化。只需要进行配置就可以实现全文检索服务。有效降低频繁访问数据库对数据库造成的压力。


六、Nginx
  
1. Nginx是一个高性能的HTTP和反向代理服务器,同时也是电子邮件(IMAP/POP3) 代理服务器
2. nginx 负载均衡5种配置方式(我主要用3种)
轮询(默认)、
weight(权重weight=5)、
ip_hash(每个请求按访问ip的hash结果分配,绑定一个后端服务器,可以解决session 的问题)


3. 在upstream中定义分布式设备的Ip及设备状态,
其中每一台设备的状态可以设置为:
1.down 表示当前的server暂时不参与负载  
2.weight 默认为1.weight越大,负载的权重就越大。  
3.max_fails :允许请求失败的次数默认为1.当超过最大次数时,返回 proxy_next_upstream 模块定义的错误  
4.fail_timeout:max_fails次失败后,暂停的时间。  
5.backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。 相当于备胎。  
4. 为什么Nginx性能这么高?
    得益于它的事件处理机制:异步非阻塞事件处理机制


5. Nginx和apache比较
Nginx优点:
Nginx更加轻量级,比apache占用更少内存及资源,可以做到秒起秒关;
Nginx所有请求由一个线程处理,而apache由单个线程处理单个请求;
Nginx处理请求是异步非阻塞的,而apache阻塞型的,所以nginx比apache更能 抗击高并发;
Nginx配置简洁,而apache复杂;nginx处理静态文件好;
但nginx bug比较少,超稳定,模块超多,rewrite强大;
需要性能的web服务,用nginx 。如果不需要性能只求稳定,那就apache 


6. 请解释Nginx服务器上的Master和Worker进程分别是什么?
Master进程:读取及评估配置和维持
Worker进程:处理请求


七、Amoeba和数据库主从复制
1. 数据库主从
调用原理
1.当主库更新数据后,会实时的写入到二进制日志文件中
2.从库的IO线程,实时的监听主库的二进制文件,如果二进制文件发生了改变则启动 线程进行读取修改后的内容.
3.通过IO线程将读取的二进制文件写入到中继日志中.
4.Sql线程实时读取中继日志中的消息,进行数据库的"更新操作"


二进制日志文件 vim  /etc/my.cnf:log-bin=mysql-bin
挂在到主数据库上:change master to MASTER_HOST=...


2. Amoeba是一个以MySQL为底层数据存储,并对应用提供MySQL协议接口的proxy。 它集中地响应应用的请求,依据用户事先设置的规则,将SQL请求发送到特定的数据库 上执行。基于此可以实现负载均衡、读写分离、高可用性等需求。
3. Amoeba的负载均衡也有三种:轮询,权重和hashIP 
4. dbserver.xml:用来存储和配置Amoeba所代理的数据库服务器的信息
dbserver标签配置数据库属性,dbserver的poolconfig配置
Amoeba.xml:用来配置Amoeba服务的基本参数和数据库的读写分离,如Amoeba 主机地址、端口




八、redis
1. Redis 是一个基于内存的高性能key-value数据库。


2. 使用redis有哪些好处?
(1) 速度快,每秒可以处理超过 10万次读写操作,是已知性能最快的 Key-Value DB。
(2) 支持丰富数据类型,支持string,list,set,zset(有序集合),hash等数据结 构的存储
(3) 支持事务,操作都是原子性
(4) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除


3. Redis是单进程单线程的,redis利用队列技术将并发访问变为串行访问,消除了传 统数据库串行控制的开销;


5. redis主从是怎么选取的


6. 与memcached比较
(1) memcached所有的值均是简单的字符串,redis支持更为丰富的数据类型
(2) redis的速度比memcached快很多
(3) redis支持数据落地,而memcached不支持
(4)value大小redis最大可以达到1GB,而memcache只有1MB


7. redis常见性能问题和解决方案:
(1) Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件 
(2) 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次 
(3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内 
(4) 尽量避免在压力很大的主库上增加从库 
(5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2


8. mySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据。
  redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略:
  (1)volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
  (2)volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
  (3)volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
  (4)allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
  (5)allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
  (6)no-enviction(驱逐):禁止驱逐数据




九、Linux常用命令:
ls——列出当前路径下的文件名或目录
ll——列出当前路径下的文件名或目录的详细信息
pwd——显示当前路径位置
cd——切换目录
ping  ip地址——测试网络连接是否畅通
vim  文件名称——修改文件
i——进入编辑状态
esc——退出上一状态
:wq——保存退出
:q!——表示强制退出      不建议使用
cp   原文件名称  复制文件名称——复制文件
mv  a.txt  b.txt——将a.txt改名为b.txt
mv a.txt  aa/——将a.txt 移动到aa文件夹
clear——清屏命令
service  iptables  stop——关闭防火墙,start 开启
rm  a.txt——表示删除单个文件
rm  -rf  aa——强制删除文件
tar  -xvf  a.tar——解压a.tar