文档

java体系技术文档


面试总结

<h2>操作系统页面置换算法</h2> <ul> <li>LRU最近最少使用算法</li> <li>FIFO先进先出算法</li> <li>时钟轮转算法</li> </ul> <h2>一致性哈希的长问道问题</h2> <p>详情请看:<a href="https://www.jianshu.com/p/e968c081f563">一致性hash</a></p> <h2>大文件排序问题</h2> <p>思路:内存极少的情况下,利用分治策略,利用外存保存中间结果,再用多路归并来排序。</p> <ol> <li>按可用内存的大小,把外存上含有n个记录的文件分成若干个长度为L的子文件,把这些子文件依次读入内存,并利用有效的内部排序方法对它们进行排序,再将排序后得到的有序子文件重新写入外存;</li> <li>对这些有序子文件逐趟归并,使其逐渐由小到大,直至得到整个有序文件为止。</li> </ol> <h2>大文件重复数问题</h2> <p>思路:hash,分治法;经过hash取模分组,相同的数据都会被分在同一个组里面,然后在通过多路归并排序,最后找出重复数。</p> <ol> <li>采用hash算法对A文件进行hash成a个小文件</li> <li>采取同样的hash算法对B文件进行hash成b个小文件</li> <li>比较小文件对&lt;a1,b1&gt;.........因为hash的问题,所以相同的字符串肯定在同个文件对里面。</li> <li>统计小文件对,可以继续采用hash,对a1的每一字符串建立hash表,遍历b1的字符串看是否在之前构建的hash表里面(和上面一样)</li> </ol> <h2>cookie和session的区别</h2> <ol> <li>cookie数据存放在客户的浏览器上,session数据放在服务器上;</li> <li>cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session;</li> <li>session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用COOKIE。</li> </ol> <h2>Redis实现限流功能</h2> <h2>nginx负载均衡策略</h2> <ol> <li>轮询;</li> <li>权重(weight);</li> <li>最少连接(lest_conn);</li> <li>会话持久性(ip_hash);</li> </ol> <h2>五张牌判断是否是同花顺</h2> <ol> <li>先判断这五张牌是不是同花;</li> <li>将这五张牌进行排序;</li> <li>排序后相邻两张牌两两相减,并对相减的结果进行记录;</li> <li>判断结果是否为4个1,是则是同花顺,否则不是;</li> </ol> <h2>NIO和IO的区别</h2> <ol> <li>IO流是阻塞的,NIO是非阻塞的;</li> <li>Buffer(缓冲区),IO 面向流,而 NIO 面向缓冲区;</li> <li>Channel (通道),NIO 通过Channel(通道) 进行读写;通道是双向的,可读也可写,而流的读写是单向的。无论读写,通道只能和Buffer交互。因为 Buffer,通道可以异步地读写。</li> <li>Selector (选择器),NIO有选择器,而IO没有;选择器用于使用单个线程处理多个通道。</li> </ol> <h2>扫码登录原理</h2> <ol> <li>打开网页的时候向服务器发送获取登录二维码的请求;</li> <li>服务端二维码生成,获取唯一标识,存入Redis,生成二维码,响应给前端;</li> <li>前端收到响应,将二维码展示出来;</li> <li>定时扫描二维码与用户的对应关系,查询用户与唯一标识是否匹配,匹配则登录成功;</li> <li>登录成功;</li> </ol> <h2>redis实现限流</h2> <ol> <li>使用令牌桶算法,在list中每秒放入N个令牌,然后需要执行的线程从list中取令牌,如果能取到,就执行;否则就等待或者降级。</li> <li>使用滑动窗口实现,利用zset数据结构实现,通过range函数来获取一段区间的元素</li> </ol> <h2>MySQL性能瓶颈</h2> <p><strong> 常用工具 </strong></p> <ul> <li>show [SESSION | GLOBAL] variables     查看数据库参数信息</li> <li>SHOW [SESSION | GLOBAL] STATUS        查看数据库的状态信息</li> <li>information_schema                    获取元数据的方法</li> <li>SHOW ENGINE INNODB STATUS             Innodb引擎的所有状态</li> <li>SHOW PROCESSLIST                      查看当前所有连接session状态</li> <li>explain                               获取查询语句的执行计划</li> <li>show index 查看表的索引信息</li> <li>slow-log 记录慢查询语句</li> <li>show status like '%lock%' 查询锁状态</li> </ul> <h2>web攻击技术有哪些</h2> <ul> <li>XSS,跨站脚本攻击 允许攻击者将恶意代码植入到提供给其它用户使用的页面中;攻击目标是为了盗取存储在客户端的cookie或者其他网站用于识别客户端身份的●●信息。 解决方法:1. 过滤特殊字符(如:script标签);2. 使用HTTP头指定类型;3.不要使用 innerHTML,改成 innerText,script 就会被当成文本,不执行;</li> <li>SQL注入 攻击者成功的向服务器提交恶意的SQL查询代码,导致原始的查询逻辑被改变,额外的执行了攻击者精心构造的恶意代码。 解决方法:1. 使用预编译(PreparedStatement)SQL语句,进行参数的传递;2. 使用专业的SQL注入●●工具进行●●,以及时修补被发现的SQL注入漏洞;</li> <li>DDOS,分布式拒绝服务攻击 发送大量请求使服务器瘫痪。 解决方法:1. ●●技术,●●网站是否正在遭受 DDoS 攻击;2.清洗技术,就是清洗过滤掉异常流量。</li> <li>CSRF,跨站请求伪造 可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。 解决办法:1.在请求地址中添加 token 并验证;2.验证 HTTP Referer 字段;3.同源策略。 <h3>总结</h3> <p>上面一共提到了4种攻击方式,分别是XSS攻击(关键是脚本,利用恶意脚本发起攻击),SQL注入(关键是通过用SQL语句伪造参数发出攻击),DDOS攻击(关键是发出大量请求,最后令服务器崩溃),CSRF攻击(关键是借助本地cookie进行认证,伪造发送请求)。</p></li> </ul> <h2>同源策略</h2> <p>同源策略是一个著名的安全策略;所谓同源是指,域名,协议,端口均相同。浏览器处于安全方面的考虑,只允许本域名下的接口交互,不同源的客户端脚本,在没有明确授权的情况下,不能读写对方的资源。</p> <h2>jvm调优</h2> <p>-Xmx4g:堆内存最大值为4GB。 -Xms4g:初始化堆内存大小为4GB。 -Xmn1200m:设置年轻代大小为1200MB。 -Xss512k:设置每个线程的堆栈大小。 -XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。 -XX:SurvivorRatio=8:设置年轻代中Eden区与Survivor区的大小比值。</p> <h2>jstat、jstack</h2> <p><a href="https://www.jianshu.com/p/213710fb9e40">jstat</a> <a href="https://www.jianshu.com/p/6690f7e92f27">jstack</a></p> <h2>分布式事务</h2> <p><a href="https://www.cnblogs.com/savorboard/p/distributed-system-transaction-consistency.html">分布式事务</a></p> <h2>Spring cloud 和dubbo的区别</h2> <table> <thead> <tr> <th style="text-align: center;">功能</th> <th style="text-align: center;">Dubbo</th> <th style="text-align: center;">Spring Cloud</th> </tr> </thead> <tbody> <tr> <td style="text-align: center;">服务注册中心</td> <td style="text-align: center;">Zookeeper</td> <td style="text-align: center;">Spring Cloud Netflix Eureka</td> </tr> <tr> <td style="text-align: center;">服务调用方式</td> <td style="text-align: center;">RPC</td> <td style="text-align: center;">REST API</td> </tr> <tr> <td style="text-align: center;">服务监控</td> <td style="text-align: center;">Dubbo-monitor</td> <td style="text-align: center;">Spring Boot Admin</td> </tr> <tr> <td style="text-align: center;">断路器</td> <td style="text-align: center;">不完善</td> <td style="text-align: center;">Spring Cloud Netflix Hystrix</td> </tr> <tr> <td style="text-align: center;">服务网关</td> <td style="text-align: center;">无</td> <td style="text-align: center;">Spring Cloud Netflix Zuul</td> </tr> <tr> <td style="text-align: center;">分布式配置</td> <td style="text-align: center;">无</td> <td style="text-align: center;">Spring Cloud Config</td> </tr> <tr> <td style="text-align: center;">服务跟踪</td> <td style="text-align: center;">无</td> <td style="text-align: center;">Spring Cloud Sleuth</td> </tr> <tr> <td style="text-align: center;">消息总线</td> <td style="text-align: center;">无</td> <td style="text-align: center;">Spring Cloud Bus</td> </tr> <tr> <td style="text-align: center;">数据流</td> <td style="text-align: center;">无</td> <td style="text-align: center;">Spring Cloud Stream</td> </tr> <tr> <td style="text-align: center;">批量任务</td> <td style="text-align: center;">无</td> <td style="text-align: center;">Spring Cloud Task</td> </tr> </tbody> </table> <p>Dubbo和Spring Cloud并不是完全的竞争关系,两者所解决的问题域不一样:Dubbo的定位始终是一款RPC框架,而Spring Cloud的目的是微服务架构下的一站式解决方案。</p> <h2>分表后如何统计查询</h2> <p>分表之后最好就不要做全局的统计查询了,分表的时候就要想好如何分,比如按照客户id来分或时间来分,如果实在需要统计,则</p> <ol> <li>使用union来关联各个表查询到的数据;</li> <li>第三方分库分表工具不知道是否有相对应的解决方法(如:mycat)</li> </ol> <h2>如何停止一个运行中的线程</h2> <ul> <li>使用stop方法强行终止,但是不推荐这个方法,因为stop和suspend及resume一样都是过期作废的方法。</li> <li>使用interrupt方法中断线程。</li> </ul> <h2>深克隆和浅克隆</h2> <ol> <li>浅克隆:只复制基本类型的数据,引用类型的数据只复制了引用的地址,引用的对象并没有复制,在新的对象中修改引用类型的数据会影响原对象中的引用。直接使用clone方法,再嵌套的还是浅克隆,因为有些引用类型不能直接克隆。</li> <li>深克隆:是在引用类型的类中也实现了clone,是clone的嵌套,并且在clone方法中又对没有clone方法的引用类型又做差异化复制,克隆后的对象与原对象之间完全不会影响,但是内容完全相同。</li> <li>使用序列化也能完成深复制的功能:对象序列化后写入流中,此时也就不存在引用什么的概念了,再从流中读取,生成新的对象,新对象和原对象之间也是完全互不影响的。</li> </ol> <h2>如何快速将大量数据插库</h2> <ol> <li>一条sql语句插入多条数据;</li> <li>在事务中进行批量插入处理;</li> <li>数据的有序插入;</li> <li>结合前面三种方法插入;</li> </ol> <h2>分布式事务</h2> <ul> <li> <p>两阶段提交方案/XA方案 所谓的 XA 方案,即:两阶段提交,有一个事务管理器的概念,负责协调多个数据库(资源管理器)的事务,事务管理器先问问各个数据库你准备好了吗?如果每个数据库都回复 ok,那么就正式提交事务,在各个数据库上执行操作;如果任何其中一个数据库回答不 ok,那么就回滚事务。</p> </li> <li> <p>TCC方案 TCC 的全称是:Try、Confirm、Cancel。 Try 阶段:这个阶段说的是对各个服务的资源做●●以及对资源进行锁定或者预留。 Confirm 阶段:这个阶段说的是在各个服务中执行实际的操作。 Cancel 阶段:如果任何一个服务的业务方法执行出错,那么这里就需要进行补偿,就是执行已经执行成功的业务逻辑的回滚操作。(把那些执行成功的回滚)</p> </li> <li>可靠消息最终一致性方案 直接基于 MQ 来实现事务。 <ol> <li>A 系统先发送一个 prepared 消息到 mq,如果这个 prepared 消息发送失败那么就直接取消操作别执行了;</li> <li>如果这个消息发送成功过了,那么接着执行本地事务,如果成功就告诉 mq 发送确认消息,如果失败就告诉 mq 回滚消息;</li> <li>如果发送了确认消息,那么此时 B 系统会接收到确认消息,然后执行本地的事务;</li> <li>mq 会自动定时轮询所有 prepared 消息回调你的接口,问你,这个消息是不是本地事务处理失败了,所有没发送确认的消息,是继续重试还是回滚?一般来说这里你就可以查下数据库看之前本地事务是否执行,如果回滚了,那么这里也回滚吧。这个就是避免可能5. 本地事务执行成功了,而确认消息却发送失败了。</li> <li>这个方案里,要是系统 B 的事务失败了咋办?重试咯,自动不断重试直到成功,如果实在是不行,要么就是针对重要的资金类业务进行回滚,比如 B 系统本地回滚后,想办法通知系统 A 也回滚;或者是发送报警由人工来手工回滚和补偿。</li> <li>这个还是比较合适的,目前国内互联网公司大都是这么玩儿的,要不你举用 RocketMQ 支持的,要不你就自己基于类似 ActiveMQ?RabbitMQ?自己封装一套类似的逻辑出来,总之思路就是这样子的。</li> </ol></li> </ul> <h2>获取线程池中的任务数</h2> <ul> <li>executor.getTaskCount();</li> <li>executor.getActiveCount();</li> <li>executor.getCompletedTaskCount();</li> </ul> <h2>内存泄漏的原因和解决办法</h2> <p>内存泄漏:不再使用的对象但是无法被回收掉,就会导致内存泄漏;内存泄漏会导致内存溢出(OOM,系统要申请内存来分配对象,但是已经没有内存可以申请了)。 产生原因:</p> <ol> <li>内存中加载的数据量过于庞大,如一次从数据库取出过多数据;</li> <li>集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;</li> <li>代码中存在死循环或循环产生过多重复的对象实体;</li> </ol> <h2>dubbo常用注解及参数</h2> <p>@Service @Reference 常用参数:version、check、timeout、retries、loadbalance、failfast</p> <h2>数据库三范式</h2> <ul> <li>1NF:数据表的每一列都要保持它的原子特性,也就是列不能再被分割;</li> <li>2NF:在1NF的基础上建立起来的,有主键,非主键字段完全依赖主键,而不能只依赖主键的一部分;</li> <li>3NF:在2NF的基础上建立起来的,非主键字段必须直接依赖于主键,而不能依赖于其它非主键字段再传递依赖于主键;</li> </ul> <h2>Redis集群</h2> <p>主从+哨兵</p> <h2>死锁及解决方式</h2> <p>死锁是多个线程循环等待资源,互相等待对方释放资源,导致所有线程都拿不到资源而阻塞。 <strong>产生条件:</strong></p> <ul> <li>互斥(资源独占): 一个资源每次只能被一个进程使用;</li> <li>请求与保持(部分分配,占有申请):一个进程在申请新的资源的同时保持对原有资源的占有(只有这样才是动态申请,动态分配);</li> <li>不可剥夺(不可强占):资源申请者不能强行地从资源占有者手中夺取资源,资源只能由占有者自愿释放;</li> <li>循环等待:若干进程之间形成一种头尾相连的循环等待资源关。</li> </ul> <h2>TCP如何保证可靠性传输</h2> <ul> <li>校验和:这是一个端到端的检验和,目的是●●数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。</li> <li>流量控制:TCP 利用滑动窗口实现流量控制。流量控制是为了控制发送方发送速率,保证接收方来得及接收。</li> <li>拥塞控制:当网络拥塞时,减少数据的发送。(慢启动、拥塞避免、快重传与快恢复)</li> <li>超时重传:当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。</li> <li>面向连接:TCP三次握手连接</li> </ul> <p>与UDP的区别:</p> <ol> <li>是否面向连接;</li> <li>是否可靠性传输;</li> <li>传输效率如何;</li> <li>传输的形式是数据报还是字节流;</li> </ol> <h2>常见状态码</h2> <ul> <li>200:请求成功</li> <li>301:重定向</li> <li>302:跳转</li> <li>404:请求不到资源</li> <li>500:服务端错误</li> </ul> <h2>MySQL主从复制</h2> <ul> <li>异步复制:MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后只会通知一下 Dump 线程发送这些新的 Binlog,然后主库就会继续处理提交操作,并不关心从库是否已经接收并处理。</li> <li>全同步复制:当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。</li> <li>半同步复制:是介于全同步复制与全异步复制之间的一种,主库只需要等待至少一个从库节点收到并且 Flush Binlog 到 Relay Log 文件即可,从库不需要执行完事务,主库不需要等待所有从库给主库反馈。</li> </ul>

页面列表

ITEM_HTML