面试总结

1.数据库优化,sql优化:聚簇索引、联合索引、单索引

索引(Index)是帮助MySQL高效获取数据的数据结构,占用内存空间。数据库系统维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。
数据库优化的几个方面:
(1)根据服务层面:配置mysql性能优化参数,在MySQL配置文件my.cnf 通过根据服务器目前状况,修改Mysql的系统参数,达到合理利用服务器现有资源,最大合理的提高MySQL性能。
例如:32G内存、4个CPU,每个CPU 8核
a.修改back_log参数值:由默认的50修改为500.(每个连接256kb,占用:125M)
back_log=500
MySQL客户端的数据库连接闲置最大时间值。
b .修改wait_timeout参数值,由默认的8小时,修改为30分钟。(本次不用) 等待超时时间
wait_timeout=1800(单位为秒)
c.修改max_connections参数值,由默认的151,修改为3000(750M)。 最大连接数
max_connections=3000
d.修改max_user_connections值,由默认的0,修改为800 最大用户连接
max_user_connections=800
f.修改thread_concurrency值,由目前默认的8,修改为64 线程并发数
thread_concurrency=64
e.添加skip-name-resolve,默认被注释掉,没有该参数。
skip-name-resolve
g.default-storage-engine(设置MySQL的默认存储引擎)
(2)从系统层面增强mysql的性能:优化数据表结构、字段类型、字段索引、分表,分 库、读写分离等等。
(3)从数据库层面增强性能:优化SQL语句,合理使用字段索引。
(4)从代码层面增强性能:使用缓存和NoSQL数据库方式存储,如 MongoDB/Memcached/Redis来缓解高并发下数据库查询的压力。
(5)减少数据库操作次数,尽量使用数据库访问驱动的批处理方法。
(6)不常使用的数据迁移备份,避免每次都在海量数据中去检索。
(7)提升数据库服务器硬件配置,或者搭建数据库集群。
(8)编程手段防止SQL注入:使用JDBC PreparedStatement按位插入或查询;正 则表达式过滤(非法字符串过滤);
数据库创建表时要考虑:
a、大数据字段最好剥离出单独的表,以防影响性能
b、使用varchar,代替char,这是因为varchar会动态分配长度,char指定为20, 即时你存储字符“1”,它依然是20的长度
c、给表建立主键,看到好多表没主键,这在查询和索引定义上将有一定的影响
d、避免表字段运行为null,如果不知道添加什么值,建议设置默认值,特别int类型, 比如默认值为0,在索引查询上,效率立显。
e、建立索引,聚集索引则意味着数据的物理存储顺序,最好在唯一的,非空的字段上 建立,其它索引也不是越多越好,索引在查询上优势显著,在频繁更新数据的字段上建 立聚集索引,后果很严重,插入更新相当慢。
f、组合索引和单索引的建立,要考虑查询实际和具体模式
单索引和联合索引的使用区别:
多个单列索引在多条件查询时优化器会选择最优索引策略,可能只用一个索引,也可 能将多个索引全用上! 但多个单列索引底层会建立多个B+索引树,比较占用空间,也 会浪费一定搜索效率,故如果只有多条件联合查询时最好建联合索引!
建立联合索引注意:应该将严格的索引放在前面,这样筛选的力度会更大,效率更高。
联合索引本质:当创建**(a,b,c)联合索引时,相当于创建了(a)单列索引**,(a,b)联合索 引以及**(a,b,c)联合索引**
想要索引生效的话,只能使用 a和a,b和a,b,c三种组合;当然,我们上面测试过,a,c 组合也可以,但实际上只用到了a的索引,c并没有用到!
什么情况下索引失效:
1.like的前模糊查询
2.where 条件查询中使用了函数
3.在JOIN操作中(需要从多个数据表提取数据时),MYSQL只有在主键和外键的数据类型相同时才能使用索引,否则即使建立了索引也不会使用
4.条件中有or ,必须or连接的字段都有索引才行
5.如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
6.where 条件中 = 左边有运算时,如 where id+1=2;
7.<>!= null 等等

sql优化:建立合适的索引
	1.首先应考虑在 where 及 order by 涉及的列上建立索引。
	2.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。
	3.在业务密集的SQL当中尽量不采用IN操作符,用exists方案代替。
	4.理论上,尽量使用多表连接(join)查询(避免子查询) 
2.分布式、dubbo 和zookeeper 的关系及配置

Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。
RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP/IP或UDP,为通信程序之间携带信息数据。RPC将原来的本地调用转变为调用远端的服务器上的方法,给系统的处理能力和吞吐量带来了近似于无限制提升的可能。在OSI网络通信模型中,RPC跨域了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
一体式架构和微服务架构:
微服务 :也被称为微服务体系结构 - 是一种架构风格,它将应用程序构建为一系列松散且互联的实现各自业务功能的服务。微服务架构支持大型复杂应用的持续交付/部署。
一体式架构:一体化应用程序的确解决了许多经典架构问题,例如如部署(因为它是作为一个单元部署)和测试很容易
i、可扩展性 - 扩展应用程序有可能很困难 - 一体化架构只能在一个维度上进行扩展。一方面,它可以通过运行更多的应用程序副本来扩大交易量。使用一体化架构,我们无法独立扩展每个组件,因此即使大多数组件可能不需要扩展,整个应用程序也需要进行扩展。
ii、可靠性 - 一体化应用的另一个问题是可靠性。任何模块中的一个错误(例如内存泄漏)都可能导致整个过程失败。而且由于应用程序的所有实例都是相同的,因此该错误将影响整个应用程序的可用性。
iii、可用性 - 即使一个服务失败,整个应用程序也必须关闭。由于所有服务都是作为一个单元部署的,因此每次服务失败或出现错误时,都会牵累整个应用程序。
iv、敏捷性 - 在一体化应用程序中,即使应用程序中的小型组件需要更改,整个应用程序也需要重新打包并组装在一起。因为重建整个应用程序需要相当长的时间,我们可以很确定这降低了应用程序的敏捷性。
v、持续部署 -如果您持续部署,那么它在这方面会表现会很差,因为即使应用程序发生小的变化,构建时间也会大大增加,并且会明显减少部署频率。而且即使是很小的更改,您也必须在每次更新时重新部署整个应用程序。
vi、独立软件栈 -一体化应用程序很难适应不同的软件栈。由于框架或语言的变化会影响整个应用程序,因此付出的时间和成本很大。

总而言之,一体化架构更适合简单轻量级的应用。微服务架构模式适用于复杂的,不断变化的应用程序

RPC架构

一个完整的RPC架构里面包含了四个核心的组件,分别是Client,Client Stub,Server以及Server Stub,这个Stub可以理解为存根。
客户端(Client),服务的调用方。
客户端存根(Client Stub),存放服务端的地址消息,再将客户端的请求参数打包成网络消息,然后通过网络远程发送给服务方。
服务端(Server),真正的服务提供者。
服务端存根(Server Stub),接收客户端发送过来的消息,将消息解包,并调用本地的方法。
Dubbo实现服务调用是通过RPC的方式,即客户端和服务端共用一个接口(将接口打成一个jar包,在客户端和服务端引入这个jar包),客户端面向接口写调用,服务端面向接口写实现,中间的网络通信交给框架去实现
分布式是从项目业务角度考虑划分项目整个架构。可以将项目基于功能模块划分再分别部署。Dubbo是实现分布式项目部署框架。在zookeeper是dubbo分布式框架的注册中心,管理服务的注册和调用。

调用关系说明:
服务容器负责启动(上面例子为Spring容器),加载,运行服务提供者。
服务提供者在启动时,向注册中心注册自己提供的服务。
服务消费者在启动时,向注册中心订阅自己所需的服务。
注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
2.1 Dubbo为什么选择Zookeeper,而不选择Redis

回答:
引入了ZooKeeper作为存储媒介,也就把ZooKeeper的特性引进来。
首先是负载均衡,单注册中心的承载能力是有限的,在流量达到一定程度的时候就需要分流,负载均衡就是为了分流而存在的,一个ZooKeeper群配合相应的Web应用就可以很容易达到负载均衡;
资源同步,单单有负载均衡还不够,节点之间的数据和资源需要同步,ZooKeeper集群就天然具备有这样的功能;
命名服务,将树状结构用于维护全局的服务地址列表,服务提供者在启动 的时候,向ZK上的指定节点/dubbo/${serviceName}/providers目录下写入自己的URL地址,这个操作就完成了服务的发布。 其他特性还有Mast选举,分布式锁等。

3.数据库事务
  • 事物是数据库操作的最小单元,是作为单个逻辑执行的一系列操作,这些操作作为一个整体一起向系统提交,要么都执行,要么都不执行,事务是一组不可分割的操作集合。
  • 事务特性:原子性:不可分割、一致性:要么都执行,要么都不执行、隔离性:事务之间不受影响、持久性:写入数据库后,就不能再回滚了
  • 数据库事务的隔离级别有4种,由低到高分别为Read uncommitted 读未提交、Read committed 读已提交、Repeatable read 可重复读、Serializable 串行化。解决在事务的并发操作中可能会出现脏读,不可重复读,幻读问题。
  • 读未提交,顾名思义,就是一个事务可以读取另一个未提交事务的数据。
  • 读提交,顾名思义,就是一个事务要等另一个事务提交后才能读取数据。
  • 重复读,就是在开始读取数据(事务开启)时,不再允许修改操作
  • 分析:重复读可以解决不可重复读问题。写到这里,应该明白的一点就是,不可重复读对应的是修改,即UPDATE操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。
  • 串行化, 是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。
  • 值得一提的是:大多数数据库默认的事务隔离级别是Read committed,比如Sql Server , Oracle。Mysql的默认隔离级别是Repeatable read。
4.spring 的DI IOC 和 AOP
  • IOC:控制反转,这里的控制指把控制权从应用程序中剥离出来。ioc它可以把创建对象和查找依赖对象的权限交给Ioc容器控制,而不是传统的由这些对象的使用方(消费者)进行创建初始化操作。IoC是一种让服务消费者不直接依赖于服务提供者的组件设计方式,是一种减少类与类之间依赖的设计原则。
  • DI:依赖注入,指容器复制创建和维护对象之间的依赖关系,而不是通过对象本身复制自己的创建和解决自己的依赖。控制反转是通过依赖注入实现的。其实Ioc和DI在Spring中是一个等同的概念。如果非要咬文嚼字的话,控制反转是依赖注入的一部分,或者说是同一个行为偏重点不同的俩个称呼。他们是从不同的角度阐述同一个功能,描述的对象不同而已。依赖注入是从程序本身来说,控制反转是从容器来说的。
  • AOP:AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。
    Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理。JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK动态代理的核心是InvocationHandler接口和Proxy类。如果目标类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。
    AOP在事务管理方面,Spring使用AOP来完成声明式的事务管理有annotation和xml两种形式。开发中,方便代码编写,很多时候都是在spring配置文件中配置事务管理器并开启事务控制注解。在业务类或业务类方法中添加@Transactional实现事务控制。
5.redis的使用
做缓存 有事务
  • redis在项目中应用:1.主要应用在门户网站首页广告信息的缓存。因为门户网站访问量较大,将广告缓存到redis中,可以降低数据库访问压力,提高查询性能。2.应用在用户注册验证码缓存。利用redis设置过期时间,当超过指定时间后,redis清理验证码,使过期的验证码无效。3.用在购物车模块,用户登陆系统后,添加的购物车数据需要保存到redis缓存中。
  • 使用redis主要是减少系统数据库访问压力。从缓存中查询数据,也提高了查询性能,挺高用户体验度。
  • redis是原子性的。对于redis而言,命令的原子性指的是:一个操作的不可以再分,操作要么执行,要么不执行。redis的操作之所以是原子性的,是因为redis是单线程的。对redis来说,执行get、set以及eval等API,都是一个一个的任务,这些任务都会由redis的线程去负责执行,任务要么执行成功,要么执行失败,这就是redis的命令是原子性的原因。redis本身提供的所有API都是原子操作,redis中的事务其实是要保证批量操作的原子性。
Redis持久化
  • 默认RDB方式 :RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照
  • AOF方式 :AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。 AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。 Redis 还可以在后台对 AOF 文件进行重写(rewrite),使得 AOF 文件的体积不会超出保存数据集状态所需的实际大小
    Redis 还可以同时使用 AOF 持久化和 RDB 持久化。 在这种情况下, 当 Redis 重启时, 它会优先使用 AOF 文件来还原数据集, 因为 AOF 文件保存的数据集通常比 RDB 文件所保存的数据集更完整。
6.http 请求的理解
http请求的过程:七步

	1.建立TCP连接
	2.web浏览器向web服务器发送请求命令
	3.web浏览器发送请求头信息
	4.web服务器应答
	5.web服务器发送应答头信息
	6.web服务器向浏览器发送数据
	7.web服务器关闭TCP连接

一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码: Connection:keep-alive TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。

https 怎么保证数据传输是安全的
  对称加密:客户端将数据通过密钥加密后再发送,服务器接收到后再通过相同的密钥解密
	特点:加密和解密的密钥相同
	问题:网络是不安全的,如何实现密钥的安全传输?
  非对称加密 :客户端和服务器都有两个密钥,分别是公钥和私钥,公钥谁都可以获得,私钥只有自己知道,公钥加密的数据可以通过对应的私钥解密。客户端通过服务器的公钥加密数据传输,服务器收到数据使用自己的私钥解密
特点:发送方和接收方各持有一对钥匙(公钥 和私钥),用公钥(私钥)加密的数据只有对用的私钥(公钥)才能解密。
  数字证书
7.Linux 命令
操作目录
  创建目录:mkdir
  拷贝:cp
  复制/更新:mv
  删除:rm
  查:  ls  查看该目录下的文件和目录
		ls -a 查看该目录下的文件和目录,包括隐藏的
		ll:查看详细信息
		搜索目录:find 目录/参数/文件名

操作文件:
  创建文件:touch 文件名
  查看文件:cat/less/tail/head/more 文件
	cat:只能看最后一屏
	more:可以显示百分比,回车下一行,空格下一页,q退出
	less:可以使用PgUp PgDn 上下翻页 q结束查看
	tail -10: 查看文件后10行 ctrl+c结束
	head -10:查看文件前10行 ctrl+c结束
	
修改文件:vim进入文件-->按i/a/o进入编辑模式-->esc退出编辑模式-->
			shift+:进入底行-->wq保存退出/q!强制退出不保存
搜索命令:grep 字符串/文件名
压缩:tar -zcvf
解压:tar -xvf
查看进程:ps -ef
查看端口:lsof -i | grep user 
查看是否有nginx 进程存在:ps -ef | grep nginx
sed -n '1,5p;5q' example.txt 查看从第一行到第5行内容 
sed -n '5p;5q' example.txt 查看第5行 
cat -n file1 标示文件的行数 
8.tomcat 和 nginx
a、设计目的:
 tomcat是一个免费的开源的servlet容器,实现了javaee的规范,遵循http协议的服务器;
 nginx是一种高性能的http和反向代理的服务器,同时也是一个代理邮件的服务器。
b、存放内容:
 tomcat可以存放静态资源和动态资源
 nginx可以存放静态资源
c、应用场景
 tomcat是用来开发和测试javaweb应用程序
 nginx是用来做负载均衡的服务器

※Tomcat调优:它的优化主要有三方面,分为
a.系统优化
b.Tomcat 本身的优化
c.Java 虚拟机(JVM)调优。
以 Tomcat 7 为例

  • Tomcat 本身的优化:Tomcat 的自身参数的优化。修改一下 xml 配置文件中的参数,调整最大连接数,超时时间等。
    a、工作方式选择
    为了提升性能,首先就要对代码进行动静分离,让 Tomcat 只负责 jsp 文件的解析工作。如采用 Apache 和 Tomcat 的整合方式,他们之间的连接方案有三种选择,JK、http_proxy 和 ajp_proxy。相对于 JK 的连接方式,后两种在配置上比较简单的,灵活性方面也一点都不逊色。但就稳定性而言不像JK 这样久经考验,所以建议采用 JK 的连接方式。
    b 、Connector 连接器的配置, Tomcat 连接器的三种方式: bio、nio 和 apr,三种方式性能差别很大,apr 的性能最优, bio 的性能最差。而 Tomcat 7 使用的 Connector 默认就启用的 Apr 协议,但需要系统安装 Apr 库,否则就会使用 bio 方式。
    c、配置文件优化:配置文件优化其实就是对 server.xml 优化,可以大大提高 Tomcat 的处理请求的能力 几个主要的配置:修改最大线程数(默认是200)/最小空闲线程数(默认10)/最大备用线程数/线程最大空闲时间 60 秒 修改<Connector …>节点:网络连接超时,一般设置为30000毫秒/是否反查域名 ,设置为false可以提升性能/disableUploadTimeout:上传时是否使用超时机制 false/
    acceptCount:指定当所有可以使用的处理请求的线程数都被使用时,可传入连接请求的最大队列长度,超过这个数的请求将不予处理,默认为100个,改成大一点:200或300

  • Jvm优化:
    set CATALINA_OPTS="
    -server
    -Xms6000M
    -Xmx6000M
    -Xss512k
    -XX:NewSize=2250M
    -XX:MaxNewSize=2250M
    -XX:PermSize=128M
    -XX:MaxPermSize=256M
    -XX:+AggressiveOpts
    -XX:+UseBiasedLocking
    -XX:+DisableExplicitGC
    -XX:+UseParNewGC
    -XX:+UseConcMarkSweepGC
    -XX:MaxTenuringThreshold=31
    -XX:+CMSParallelRemarkEnabled
    -XX:+UseCMSCompactAtFullCollection
    -XX:LargePageSizeInBytes=128m
    -XX:+UseFastAccessorMethods
    -XX:+UseCMSInitiatingOccupancyOnly
    -Duser.timezone=Asia/Shanghai
    -Djava.awt.headless=true"
    你可以在bin/catalina.sh中设置jvm所能使用到的缓存大小,如下:
    JAVA_OPTS=’-Xms1024m -Xmx1024m’
    -Xms:表示 Java 初始化堆的大小,默认值为物理内存的 1/64。
    -Xmx:表示最大 Java 堆大小,当应用程序需要的内存超出堆的最大值时虚拟机就会提示内存溢出,并且导致应用服务崩溃,因此一般建议堆的最大值设置为可用内存的最大值的80%。如何知道我的 JVM 能够使用最大值,使用 java -Xmx512M -version 命令来进行测试,然后逐渐的增大 512 的值,如果执行正常就表示指定的内存大小可用,否则会打印错误信息,默认值为物理内存的 1/4,默认(MinHeapFreeRatio参数可以调整)空余堆内存大于 70% 时,JVM 会减少堆直到-Xms 的最小限制。
    -Xss:表示每个 Java 线程堆栈大小,JDK 5.0 以后每个线程堆栈大小为 1M,以前每个线程堆栈大小为 256K。根据应用的线程所需内存大小进行调整,在相同物理内存下,减小这个值能生成更多的线程,但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在 3000~5000 左右。一般小的应用, 如果栈不是很深, 应该是128k 够用的,大的应用建议使用 256k 或 512K,一般不易设置超过 1M,要不然容易出现out ofmemory。这个选项对性能影响比较大,需要严格的测试
    -XX:NewSize:设置新生代内存大小。
    -XX:MaxNewSize:设置最大新生代内存大小
    -XX:PermSize:设置持久代内存大小

9.多线程的使用
使用多线程的4种方式:
					1.继承Thread类,
					 2.实现Runnable 接口
					 3.实现Callable接口
					 4.使用ExecutorService、Callable、Future实现有返回结果的线程
多线程的使用场景:
10.文件上传功能
11.springBoot、spring、springMVC的区别
springMVC<spring<springBoot
  • springBoot是一个大框架,将spring,springmvc,springData jpa等基础框架整合,按照约定大于配置,提供默认的配置,帮助开发者专注于代码的业务,简化搭建项目的时间,做到开箱即用的效果
    springmvc是基于servlet的一个mvc框架,主要解决web开发的问题。因为spring的配置太复杂,所以springboot诞生
  • 以前web应用使用tomcat启动,而springboot内置了服务器,通过@SpringBootApplication 注解类中main函数启动即可
    为什么?重点关注三个注解
    i、@SpringBootConfiguration 表明了这是一个配置类
    ii、@EnableAutoConfiguration 开启自动装配 Spring Boot会自动根据你jar包的依赖来自动配置项目
    iii、@ComponentScan 包扫描,用来扫描组件的,以前在ssm项目中我们需要去配置我们的包扫描
12.gc垃圾回收机制的内容,回收垃圾的计算方式:
	标记清除 和 引用计数
13.分布式及分布式锁机制
a.基于数据库实现分布式锁 (乐观锁,悲观锁)
b.基于缓存(redis,memcached,tair)实现分布式锁 
c.基于zookeeper实现分布式锁
14、常用的数据结构及算法
  • a.数组:数组是一种大小固定的数据结构,对线性表的所有操作都可以通过数组来实现。虽然数组一旦创建之后,它的大小就无法改变了,但是当数组不能再存储线性表中的新元素时,我们可以创建一个新的大的数组来替换当前数组。这样就可以使用数组实现动态的数据结构。
  • b.链表:链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列节点组成,这些节点不必在内存中相连。每个节点由数据部分Data和链部分Next,Next指向下一个节点,这样当添加或者删除时,只需要改变相关节点的Next的指向,效率很高。
  • c.栈:栈是限制插入和删除只能在一个位置上进行的表,该位置是表的末端,叫作栈顶,对栈的基本操作有push(进栈)和pop(出栈),前者相当于插入,后者相当于删除最后一个元素。栈有时又叫作LIFO(Last In First Out)表,即后进先出。
  • d.队列:普通的队列是一种先进先出的数据结构,而优先队列中,元素都被赋予优先级。当访问元素的时候,具有最高优先级的元素最先被删除。优先队列在生活中的应用还是比较多的,比如医院的急症室为病人赋予优先级,具有最高优先级的病人最先得到治疗。在Java集合框架中,类PriorityQueue就是优先队列的实现类,具体大家可以去阅读源码。
  • e.二叉树、红黑树:
15、jvm原理及gc垃圾回收机制
  • gc垃圾回收机制:
    jvm中,程序计数器、虚拟机栈、本地方法栈都是随线程而生随线程而灭,栈随着方法的进入和退出做入栈和出栈操作,实现了自动的内存清理,因此,我们的内存垃圾回收主要集中于java堆和方法区中,在程序运行期间,这部分内存的分配和使用都是动态的.

  • 垃圾回收算法:
    a.标记 -清除算法
    b.复制算法
    c.标记-压缩(整理)算法
    d.分代收集算法

  • 调优方案:
    gc调优 主要是从减少full gc(垃圾回收器满负荷运行)的次数,可以设置相关的gc参数

16、计算类库或工具(weka、R语言、apache-commons-math)
17、Jdk1.8新特性

a、引入Lambda 表达式
b、允许在接口中定义非抽象的方法(默认方法)
c、新的日期时间API
d、扩展了对注解的支持
e、Base64编码成为了Java类库的标准。Base64类同时还提供了对URL、MIME友好的编码器与解码器。

18、map的底层
Map是以键值对来存储对象的,它的底层实际上是数组和链表来组成的

当使用put方法时,先查找出数组位置是否存在对象,通过key.hashcode对数组长度取余;存在,则把里面的链表拿出来,判断链表里面是否存在key值与传递过来的key值一样的对象,存在,则把传递过来的value取代链表key对应的value,不存在,则直接通过链表的add()方法加到链表后面;

当使用get方法时,先查找出数组位置是否存在对象,通过key.hashcode对数组长度取余;如果不存在,则返回为空,如果存在,则遍历链表,判断链表里面是否存在key值与传递过来的key值一样的对象,存在,则把key值对应的value取出返回,不存在,则返回为空;

19、解决跨域问题 (拦截器)
  • 跨域是什么?
    跨域访问,简单来说就是 A 网站的 javascript 代码试图访问 B 网站时,浏览器出于安全考虑,自动阻止了对跨域服务的访问(包括对后端数据的增删改查请求),这里浏览器统一遵循了一种策略,这个策略就是同源策略,同源策略也是浏览器最核心、最基本的安全功能。
    协议、域名、端口三者之间任意一个与当前页面地址不同都会引起跨域问题
  • 企业开发中出现跨域问题情况举例
    前后端分离的的开发模式中,前端开发人员使用本地(http://localhost)去调用我们后端准备的联调环境接口服务(http://fe-api.zhuma.com)。当项目变得庞大,业务变得复杂,很可能会出现想要直接调用第三方的某些服务来完成业务功能,这时便出现了跨域问题。
    解决方案:
    在我们的实际开发过程中,我们会使用 CORS方式,自己定义个拦截器 对开发、测试环境解决跨域问题,线上环境如果出现跨域问题会使用nginx做个代理中转的这种方式,这里说明下线上环境尽量保证 接口、页面 同一域名。
20、如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性?
 幂等性:通俗点说,就一个数据,或者一个请求,给你重复来多次,你得确保对应的数据是不会改变的,不能出错

比如你拿个数据要写库,你先根据主键查一下,如果这数据都有了,你就别插入了,update 一下好吧。
比如你是写 Redis,那没问题了,反正每次都是 set,天然幂等性。
比如你不是上面两个场景,那做的稍微复杂一点,你需要让生产者发送每条数据的时候,里面加一个全局唯一的 id,类似订单 id 之类的东西,然后你这里消费到了之后,先根据这个 id 去比如 Redis 里查一下,之前消费过吗?如果没有消费过,你就处理,然后这个 id 写 Redis。如果消费过了,那你就别处理了,保证别重复处理相同的消息即可。
比如基于数据库的唯一键来保证重复数据不会重复插入多条。因为有唯一键约束了,重复数据插入只会报错,不会导致数据库中出现脏数据。

21、SpringMVC的流程?

(1)用户发送请求至前端控制器DispatcherServlet;
(2) DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handler;
(3)处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;
(4)DispatcherServlet 调用 HandlerAdapter处理器适配器;
(5)HandlerAdapter 处理器适配器经过适配调用具体处理器(Handler,也叫后端控制器);
(6)Handler执行完成返回ModelAndView;
(7)HandlerAdapter处理器适配器将Handler执行结果ModelAndView返回给DispatcherServlet;
(8)DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;
(9)ViewResolver解析后返回具体View;
(10)DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
(11)DispatcherServlet响应用户。

  • 什么是Spring MVC ?简单介绍下你对springMVC的理解?

    Spring MVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,通过把Model,View,Controller分离,将web层进行职责解耦,把复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。

  • springMVC和struts2的区别有哪些?
    (1)springmvc的入口是一个servlet即前端控制器(DispatchServlet),而struts2入口是一个filter过虑器(StrutsPrepareAndExecuteFilter)。
    (2)springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。

22.多线程怎么实现数据共享

a、如果每个线程执行的代码相同,可以使用同一个Runnable对象,然后将共享的数据放在 Runnable里面,来实现数据的共享。 例如买票系统…
b、如果每个线程执行的代码不同, 那么就需要不同的Runnable对象

  • 第一种方式:将共享数据封装在另一个对象中,然后实现不同的操作,然后将这个新对象传递给Runnable对象,每个线程对共享数据的操作也就相应的分配到了那个对象身上去完成。这样就能够实现对该数据的各种操作的互斥与通信
  • 第二种方式:将这些Runnbale对象作为某一个类中的内部类,共享数据作为外部类的成员变量,每个线程对共享数据的操作也就分配给了外部类,以便实现共享数据的各种操作的互斥通信。
    23.聚集索引 非聚集索引
24.redis怎么存储对象
将对象序列化后存储,取出后反序列化回来。
25.dubbo的负载均衡 怎么实现服务的调用
Dubbo提供的负载均衡策略
  • Random LoadBalance:随机策略。按照概率设置权重,比较均匀,并且可以动态调节提供者的权重。
  • RoundRobin LoadBalance:轮询策略。轮询,按公约后的权重设置轮询比率。会存在执行比较慢的服务提供者堆积请求的情况,比如一个机器执行的非常慢,但是机器没有挂调用(如果挂了,那么当前机器会从Zookeeper的服务列表删除),当很多新的请求到达该机器后,由于之前的请求还没有处理完毕,会导致新的请求被堆积,久而久之,所有消费者调用这台机器上的请求都被阻塞。
  • LeastActive LoadBalance:最少活跃调用数。如果每个提供者的活跃数相同,则随机选择一个。在每个服务提供者里面维护者一个活跃数计数器,用来记录当前同时处理请求的个数,也就是并发处理任务的个数。所以如果这个值越小说明当前服务提供者处理的速度很快或者当前机器的负载比较低,所以路由选择时候就选择该活跃度最小的机器。如果一个服务提供者处理速度很慢,由于堆积,那么同时处理的请求就比较多,也就是活跃调用数目越大,这也使得慢的提供者收到更少请求,因为越慢的提供者的活跃度越来越大。
  • ConsistentHash LoadBalance:一致性Hash策略。一致性Hash,可以保证相同 参数的请求总是发到同一提供者,当某一台提供者挂了时,原本发往该提供者的请求, 基于虚拟节点,平摊到其他提供者,不会引起剧烈变动。
项目中Zookeeper服务器挂了,服务调用可以进行吗?

可以的,消费者在启动时,消费者会从zk拉取注册的生产者的地址接口等数据,缓存 在本地。每次调用时,按照本地存储的地址进行调用。

26.MyBatis中的命名空间namespace的作用

a、定义mapper接口,面向接口编程。
b、在大型项目中,可能存在大量的SQL语句,这时候为每个SQL语句起一个唯一的标识(ID)就变得并不容易了。为了解决这个问题,在MyBatis中,可以为每个映射文件起一个唯一的命名空间,这样定义在这个映射文件中的每个SQL语句就成了定义在这个命名空间中的一个ID。只要我们能够保证每个命名空间中这个ID是唯一的,即使在不同映射文件中的语句ID相同,也不会再产生冲突了。

27.构造器能否被重写?能否被重载?能否被继承?

构造器就是构造方法,能够被重载(同类中不同参数列表的构造器),不能够被重写(子类使用super方法可以调用)。不能说能被继承,因为能够调用,但是不能重写。

28.short s1 =1;s1 = s1+1;报错,因为1是整型

s1+=1; 不报错 因为s1+=1 ==> s1 = (short) (s1 + 1);
+= 运算符最后会自动进行强制转换 所以不会报错 这是c#内部自己定义

29.什么时候使用事务? (金融,涉及到钱的时候)

对数据库的数据进行批量或连表操作时,为了保证数据的一致性和正确性,我们需要添加事务管理机制进行管理。当对数据库的数据进行操作失败时,事务管理可以很好保证所有的数据回滚到原来的数据,如果操作成功,则保证所有需要更新的数据持久化。

30.springboot 的main方法怎么启动项目的?
31.微服务架构和一体式架构的区别
一体式架构:

a、功能集中,代码、数据中心化,一个发布包部署后运行在同一个进程中的应用程序
b、复杂性高:由于是单个归档文件,所以整个项目文件包含的模块非常多,导致模块 的边界模糊、依赖关系不清晰、代码的质量参差不齐,混乱的堆在一起,使得整个项目 非常复杂。以致每次修改代码,都非常小心,可能添加一个简单的功能,或者修改一个 Bug都会带来隐藏的缺陷。
c、技术债务:随着时间的推移、需求的变更和技术人员的更替,会逐渐形成应用程序 的技术债务,并且越积越多。
d、扩展能力受限:单体应用只能作为一个整体进行扩展,无法根据业务模块的需要进 行伸缩。

微服务架构:

a、微服务把每一个职责单一的功能放在一个独立的服务中。
b、每个服务有多个实例在运行,每个实例可以运行在容器化平台内,达到平滑伸缩的效 果,单个微服务启动较快。
c、每个服务应该有自己的运营平台,以及独享的运营人员,这包括技术运维和业务运营人 员:每个服务都高度自治,内部的变化对外透明。
d、易于开发和维护:一个微服务只会关注一个特定的业务功能,所以业务清晰、代码量较少。开发和维护单个微服务相对简单。
e、局部修改容易部署:单体应用只要有修改,就得重新部署整个应用。微服务解决了这样的问题。一般来说,对某个微服务进行修改,只需要重新部署这个服务即可。
f、 技术栈不受限制:在微服务架构中,可以结合项目业务及团队的特点,合理的选择技术栈。

11.13号面试:北辰泰岳 (1)

1、redis的使用,项目中怎么用的,在哪用的?使用的存储类型;

启动:redis-server
停止:redis-cli shutdown

redis使用默认不需要密码,可以在配置文件redis.conf中配置添加密码
#requirepass 123456
添加密码后重启redis服务
/usr/local/bin/redis-cli shutdown
/usr/local/bin/redis-server /usr/local/redis-5.0.6/redis.conf

a)电商项目中使用redis做首页缓存 使用hash类型
i.怎么使用?
Jedis jedis = new Jedis(“localhost”);//通过ip连接redis
String类型:
jedis.set(“123”, “111”); // 获取存储的数据并输出 jedis.get(“123”);

hash类型:
具体查看demo或redis的API

b)使用到验证码时,将验证码存入到redis中,定时5分钟后清理。(String类型)

2、项目中遇到的问题及解决。

a)Redis服务器 can not get resource from pool.
将最大连接数100改为1000/最大空闲连接数100改为500,超时时间10s改为300s解决;
b)年度统计页面:统计的数据多,查询数据库频繁,导致页面相应很慢
解决:定时将查询出来的数据存入到一张表里面,然后直接从这个表里查询

3、springboot、springcloud、double的使用

a)、服务调用方式不同:
springcloud是使用http请求的rest方式
dubbo基于RPC的方式实现
b)、dubbo只是实现了服务治理,dubbo提供了各种Filter,其他功能可以通过Filter来扩展;dubbo像是一个组装机,各环节自由度很高,但是可能一个环节出问题就会影响整个项目的运行;
springcloud下面有十几个子项目,覆盖了微服务下的方方面面;springcloud像是品牌机,保证了机器拥有更高的稳定性。

4、jvm内存分配

i.程序计数器(寄存器区)
是jvm中唯一一个不会有内存溢出的一块区域
每个线程启动的时候都会创建一个PC寄存器,用来保存当前正在执行的jvm指令的地址和下一条将要执行的指令地址。
保证调用的方法顺序执行,就是pc寄存器的作用。
ii.栈区
随方法而生,方法执行结束后,会自动释放内存
iii.堆区
主要存放实例对象的,堆区是被所有线程共享的一块内存区域,也是GC垃圾回收器管理的主要区域;
堆区可以是连续的一块内存,也可以是不连续的
可以在jvm中配置堆区大小(-Xms初始堆大小,-Xmx 最大堆大小)
iv.本地方法区
用于存储虚拟机加载的类信息,常量,静态变量,即编译器编译后的字节码文件
v.运行时常量池
是方法区的一部分,存放程序运行中产生的常量

5、项目中对多线程的使用
6、zookeeper的使用(具体见谷歌浏览器收藏)

zookeeper功能非常强大,可以实现诸如分布式应用配置管理、统一命名服务、状态同步服务、集群管理等功能,我们这里拿比较简单的分布式应用配置管理为例来说明。
假设我们的程序是分布式部署在多台机器上,如果我们要改变程序的配置文件,需要逐台机器去修改,非常麻烦,现在把这些配置全部放到zookeeper上去,保存在 zookeeper 的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到 zookeeper 的通知,然后从 zookeeper 获取新的配置信息应用到系统中。

启动zookeeper,在命令行中执行命令zkServer start来启动zookeeper。
查看zookeeper运行状态,在命令行中输入zkCli,可以查看zookeeper运行状态。

11.16号 亮马桥 平安银行 (2)

1、使用过的中间件?

ActiveMQ

2、redis做消息队列

将要发送短信的用户手机号,使用redis的list的数据类型存储,然后再取出来发送

3、Spring的常用注解

a)组件注解 用于标注类为spring容器bean的注解有四个,主要用于区别不同的组件类,提高代码的可读性
i.@Component 用于标注一个普通的bean容器
ii.@Controller 用于标注一个控制器类
iii.@Service 用于标注一个业务逻辑类
iv.@Repository 用于标注一个dao数据访问类
b)组件扫描注解
i.@ComponentScan
c)bean相关注解
i.@Bean 在@Configuration修饰的配置类中使用
ii.@Scope 该注解和@Component这一类注解联合使用,用于标记该类的作用域,默认singleton。
也可以和@Bean一起使用,此时@Scope修饰一个方法。
iii.@DependsOn({“aa”,”bb”}) 该注解也和@Component联合使用,意思为初始化该bean对象前,要先初始化aa,bb两个bean
iv.@Lazy(ture) 默认false,可以和@Component 或@Bean联合使用,指定bean是否延迟初始化,
d)bean(singleton作用域)的生命周期的行为注解
i.@PostConstruct
ii.@PreDestroy
e)自动装配
i.@Resource
ii.@Autowired
iii.@Qualifier
f)AOP 相关注解
i.@Aspect 修饰Java类,指定该类为切面类
ii.@Before 修饰方法,在目标方法执行前做增强处理,value属性指定切入点
iii.@AfterReturning 修饰方法,目标方法正常结束后做增强处理
iv.@AfterThrowing 修饰方法,目标方法抛出异常或异常无法捕获时做增强
v.@After 修饰方法,无论目标方法是否正常执行,结束后都做增强
vi.@Arround 相当于@Before+@AfterReturning 在线程安全的环境下使用
vii.@Pointcut 修饰 方法,定义一个切入点表达式被其他方法调用,易复用
viii.@Order
g)Java配置类相关注解
i.@Configuration
ii.@Import
iii.@ImportResource
iv.@Bean
v.@Value 修饰变量,将配置文件中的值注入到参数中
vi.@ConfigurationProperties 修饰类,用于从application.yml或application.properties中获取属性值
h)SpringMVC相关注解
i.@RequestBody 在Request请求体中获取内容,绑定到具体的参数上
ii.@ResponseBody 将返回内容转成JSON类型
iii.@RequestParam 在Request请求体中获取指定参数

4、dubbo启动报错问题?报空指针问题

a)使用@Reference 注入时,引用的不是阿里的dubbo
b)在同一个项目中,A服务引用B服务(都是注册到dubbo上的),在项目部署发布的时候,无法判断是哪个服务先注册到dubbo上的。所以在A服务中引用B服务,而且通过dubbo的方式注入,极有可能会产生服务注入为null的情况。那么此时在A服务中引用B服务,就可以使用spring框架带的@Autowired的注入方式,将B服务引用进来。这样就可以完美解决这个问题。
c)是SpringMVC的包扫描影响了dubbo的注解扫描,然后尝试着将dubbo的包扫描配置单独抽出来,放在SpringMVC配置的最上面,果然问题解决
d)启动顺序问题,先启动服务端,在启动客户端。

5、mapper映射文件中,resultType和resultMap的使用区别?

在使用mybatis进行数据库连接操作时对于SQL语句返回结果的处理通常有两种方式,一种就是resultType另一种就是resultMap
resultType:当使用resultType做SQL语句返回结果类型处理时,对于SQL语句查询出的字段在相应的pojo中必须有和它相同的字段对应,而resultType中的内容就是pojo在本项目中的位置。因此对于单表查询的话用resultType是最合适的
resultMap:当使用resultMap做SQL语句返回结果类型处理时,需要在mapper.xml中定义resultMap进行pojo和相应表字段的对应。
一对一对表查询时:通常为在主表的pojo中添加嵌套另一个表的pojo,然后在 mapper.xml中采用association节点元素进行对另一个表的连接处理。
一对多查询时:mapper。xml中采用collection节点元素进行对另一个表的连接处理。

11月18号 知春路 中科软 (3)

1、nginx的三部分

a)第一部分:全局块
主要设置一些影响nginx服务器整体运行的配置指令,主要配置包括运行Nginx服务器的用户(组)、允许生成worker processes的数量(值越大,支持的并发数越多,但是收到服务器硬件的限制)、进程PID存放路径、日志存放路径及类型,还有配置文件的引入等。
b)第二部分:events块
主要影响nginx服务器与用户的网络连接,常用的设置有:
是否开启对多worker processes下的网络连接进行序列化
是否允许同时接收多个网络连接,
选取哪种事件驱动模型来处理连接请求,
每个 word process 可以同时支持的最大连接数等。
这部分的配置对 Nginx 的性能影响较大,在实际中应该灵活配置
c)第三部分:http块 代理、缓存和日志定义等绝大多数功能和第三方模块的配置都 在这里。 需要注意的是:http 块也可以包括 http全局块、server 块。

2、项目部署

将打好的项目war包部署在tomcat的webapps文件夹下

3、ajax的同步异步
	ajax根据async进行区分同步和异步过程,当async=true异步,async=false	为	同步,ajax默认async为异步

a)异步:ajax不会影响整个页面的加载,相当于和浏览器加载或者用户操作分开走,互不相干,体现在用户角度就是不会有什么卡顿的感觉仿佛无事发生。
b)同步:那就与异步相反,他和加载处于同一条线上,严格按照顺序来,就是在加载它的时候,全部的过程都等停下来,也就是假死状态。

4、集群和分布式

集群:多个人在一起作同样的事 。
分布式 :多个人在一起作不同的事 。

将一套系统拆分成不同子系统部署在不同服务器上(这叫分布式),
然后部署多个相同的子系统在不同的服务器上(这叫集群),部署在不同服务器上 的同一个子系统应做负载均衡。
分布式:一个业务拆分为多个子业务,部署在多个服务器上 。
集群:同一个业务,部署在多个服务器上 。

11.19号 大家保险集团 文思海辉 (4)

Jvm内存分配

a)寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制
b)栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new出来的对象)或者常量池中(字符串常量对象存放的常量池中),局部变量【注意:(方法中的局部变量使用final修饰后,放在堆中,而不是栈中)】
c)堆:存放使用new创建的对象,全局变量
d)静态域:存放静态成员(static定义的)
e)常量池:字符串常量和基本类型常量(public static final)。有时,在嵌入式系统中,常量本身会和其他部分分割离开(由于版权等其他原因),所以在这种情况下,可以选择将其放在ROM中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值