天天看点

面试记录总结

招商局信息集团 2019年3月28日

  1. constructor
      • 1.构造器必须与类同名(如果一个源文件中有多个类,那么构造器必须与公共类同名)
      • 2.每个类可以有一个以上的构造器
      • 3.构造器可以有0个、1个或1个以上的参数
      • 4.构造器没有返回值
      • 5.构造器总是伴随着new操作一起调用
      • 6.不添加任何构造器会默认有空的构造器
  1. instr
  • instr函数返回要截取的字符串在源字符串中的位置。只检索一次,就是说从字符的开始到字符的结尾就结束
  • SELECT instr('syranmo','ra') FROM dual;  -- 返回 3
  • SELECT instr('syranmo','an',-1,1) FROM dual;  -- 返回 4
  • SELECT instr('syran mo','a',1,2) FROM dual;  -- 返回 0
  1. transient
  •  Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。
  1. jdbc如何控制事物
      • Jdbc中事物是自动提交也可通过手动进行控制
      • 在加载驱动获取连接后可以设置 手动控制事物
      • con.setAutoCommit(false);
      • 在执行数据库操作前开启事物
      • sta.excuteUpdate();执行数据库操作;
      • 利用try/catch进行捕获异常,如果异常不存在就进行事物的提交,如果异常存在就进行事物的回滚;
      • 可以通过con设置数据库的事物隔离级别;con.setTranscationInsolation();
  1. spring如何管理事务 事务的类型有哪几种
  • PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
  • PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
  • PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
  • PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
  • PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  • PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
  • PROPAGATION_REQUIRED类似的操作。
  • PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与
  1. MySQL和oracle区别,事物的区别

 (1) 对事务的提交, MySQL默认是自动提交,而Oracle默认不自动提交,需要用户手动提交,需要在写commit;指令或者点击commit按钮

(2) 分页查询, MySQL是直接在SQL语句中写"select... from ...where...limit  x, y",有limit就可以实现分页;而Oracle则是需要用到伪列ROWNUM和嵌套查询

(3) 事务隔离级别,  MySQL是read commited的隔离级别,而Oracle是repeatable read的隔离级别,同时二者都支持serializable串行化事务隔离级别,可以实现最高级别的  读一致性。每个session提交后其他session才能看到提交的更改。Oracle通过在undo表空间中构造多版本数据块来实现读一致性,每个session    查询时,如果对应的数据块发生变化,Oracle会在undo表空间中为这个session构造它查询时的旧的数据块    MySQL没有类似Oracle的构造多版本数据块的机制,只支持read commited的隔离级别。一个session读取数据时,其他session不能更改数据,但    可以在表最后插入数据。session更新数据时,要加上排它锁,其他session无法访问数据

(4) 对事务的支持    MySQL在innodb存储引擎的行级锁的情况下才可支持事务,而Oracle则完全支持事务

(5) 保存数据的持久性    MySQL是在数据库更新或者重启,则会丢失数据,Oracle把提交的sql操作线写入了在线联机日志文件中,保持到了磁盘上,可以随时恢复

(6) 并发性    MySQL以表级锁为主,对资源锁定的粒度很大,如果一个session对一个表加锁时间过长,会让其他session无法更新此表中的数据。  虽然InnoDB引擎的表可以用行级锁,但这个行级锁的机制依赖于表的索引,如果表没有索引,或者sql语句没有使用索引,那么仍然使用表级锁。  Oracle使用行级锁,对资源锁定的粒度要小很多,只是锁定sql需要的资源,并且加锁是在数据库中的数据行上,不依赖与索引。所以Oracle对并  发性的支持要好很多。

(7) 逻辑备份    MySQL逻辑备份时要锁定数据,才能保证备份的数据是一致的,影响业务正常的dml使用,Oracle逻辑备份时不锁定数据,且备份的数据是一致

(8) 复制    MySQL:复制服务器配置简单,但主库出问题时,丛库有可能丢失一定的数据。且需要手工切换丛库到主库。    Oracle:既有推或拉式的传统数据复制,也有dataguard的双机或多机容灾机制,主库出现问题是,可以自动切换备库到主库,但配置管理较复杂。

(9) 性能诊断    MySQL的诊断调优方法较少,主要有慢查询日志。    Oracle有各种成熟的性能诊断调优工具,能实现很多自动分析、诊断功能。比如awr、addm、sqltrace、tkproof等    

(10)权限与安全    MySQL的用户与主机有关,感觉没有什么意义,另外更容易被仿冒主机及ip有可乘之机。

    Oracle的权限与安全概念比较传统,中规中矩。

(11)分区表和分区索引    MySQL的分区表还不太成熟稳定。    Oracle的分区表和分区索引功能很成熟,可以提高用户访问db的体验。

(12)管理工具    MySQL管理工具较少,在linux下的管理工具的安装有时要安装额外的包(phpmyadmin, etc),有一定复杂性。    Oracle有多种成熟的命令行、图形界面、web管理工具,还有很多第三方的管理工具,管理极其方便高效。

(13)最重要的区别    MySQL是轻量型数据库,并且免费,没有服务恢复数据。    Oracle是重量型数据库,收费,Oracle公司对Oracle数据库有任何服务。

  1. https实现过程

 1.对www.baidu.com这个网址进行DNS域名解析,得到对应的IP地址

  2.根据这个IP,找到对应的服务器,发起TCP的三次握手

  3.建立TCP连接后发起HTTP请求

  4.服务器响应HTTP请求,浏览器得到html代码

  5.浏览器解析html代码,并请求html代码中的资源(如js、css图片等)(先得到html代码,才能去找这些资源)

  6.浏览器对页面进行渲染呈现给用户

注:1.DNS域名解析采用的是递归查询的方式,过程是,先去找DNS缓存->缓存找不到就去找根域名服务器->根域名又会去找下一级,这样递归查找之后,找到了,给我们的web浏览器

2.为什么HTTP协议要基于TCP来实现?  TCP是一个端到端的可靠的面相连接的协议,HTTP基于传输层TCP协议不用担心数据传输的各种问题(当发生错误时,会重传)

3.最后一步浏览器是如何对页面进行渲染的?  a)解析html文件构成 DOM树,b)解析CSS文件构成渲染树,  c)边解析,边渲染 ,  d)JS 单线程运行,JS有可能修改DOM结构,意味着JS执行完成前,后续所有资源的下载是没有必要的,所以JS是单线程,会阻塞后续资源下载

  1. 离职原因怎么说
      • 公司的组织架构调整了,与我个人的发展意向不太相符,虽然舍不得但是也真的很遗憾。
      • 公司打算做服务方向,我个人还是偏重于技术
      • 公司的薪资调整很慢,自己还是希望拿到一个相对合适的工资吧
  1. 薪资怎么说以及期望薪资
  • 说出自己的期望薪资,但是说话留有余地,说明薪资并不是我唯一的考虑条件,更重要的是这里的发展空间和锻炼机会。

小鱼科技 2019年3月28日

1.String 类为什么是Final

1.为了实现字符串池

        2.为了线程安全

        3.为了实现String可以创建HashCode不可变性

被final修饰的类不能被继承,即它不能拥有自己的子类,被final修饰的方法不能被重写, final修饰的变量,无论是类属性、对象属性、形参还是局部变量,都需要进行初始化操作

那么为什么保证String不可变呢,因为只有当字符串是不可变的,字符串池才有可能实现。字符串池的实现可以在运行时节约很多heap空间,因为不同的字符串变量都指向池中的同一个字符串。但如果字符串是可变的,那么String interning将不能实现,因为这样的话,如果变量改变了它的值,那么其它指向这个值的变量的值也会一起改变。 如果字符串是可变的,那么会引起很严重的安全问题。因为字符串是不可变的,所以是多线程安全的,同一个字符串实例可以被多个线程共享。这样便不用因为线程安全问题而使用同步。字符串自己便是线程安全的。  因为字符串是不可变的,所以在它创建的时候HashCode就被缓存了,不需要重新计算。这就使得字符串很适合作为Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键往往都使用字符串。

2.HashMap的源码和底层实现

参见博客 java面试

3.ArrayList和linkedlist的区别

参见博客 java面试

4.session和cookie的区别,session的生命周期

参见博客 java面试

5.java内存模型和GC算法

参见博客 java面试

java内存模型 jvm

6.拦截器和过滤器的区别,及应用场景

过滤器(filter)

filter是javaweb的servlet体系内,依赖servlet容器,一般用于对请求request和响应response的信息进行过滤,比如:过滤参数、字符编码、敏感字符等

拦截器(Interceptor)

interceptor是SpringMVC体系内,依赖Spring容器,基于AOP动态代理实现的,一般常用于对业务层的业务方法进行处理,比如实现系统日志、事务机制、权限检查、性能监控等,通过拦截器就比较好实现。虽然过滤器也是可以实现日志记录、权限检查等效果,但是过滤器只能在servlet前后执行,而拦截器则可以深入到方法执行前后、异常抛出前后执行,所以在Spring体系内,推荐使用拦截器进行日志和事务的实现。

7.SpringMVC的原理

8.Java创建线程后,直接调用start和run的区别

start与run方法的主要区别在于当程序调用start方法一个新线程将会被创建,并且在run方法中的代码将会在新线程上运行,然而在你直接调用run方法的时候,程序并不会创建新线程,run方法内部的代码将在当前线程上运行。大多数情况下调用run方法是一个bug或者变成失误。因为调用者的初衷是调用start方法去开启一个新的线程,这个错误可以被很多静态代码覆盖工具检测出来,比如与fingbugs. 如果你想要运行需要消耗大量时间的任务,你最好使用start方法,否则在你调用run方法的时候,你的主线程将会被卡住。另外一个区别在于,一但一个线程被启动,你不能重复调用该thread对象的start方法,调用已经启动线程的start方法将会报IllegalStateException异常, 而你却可以重复调用run方法。

9.hashmap和concurrenthaspmap的区别

10.数据库常见索引的数据结构

11.设计模式的原理 以及使用场景

12.两个有序数组的合并排序

13.Redis集群中的节点如何保证数据一致

主从复制:

1、redis的复制功能是支持多个数据库之间的数据同步。一类是主数据库(master)一类是从数据库(slave),主数据库可以进行读写操作,当发生写操作的时候自动将数据同步到从数据库,而从数据库一般是只读的,并接收主数据库同步过来的数据,一个主数据库可以有多个从数据库,而一个从数据库只能有一个主数据库。

2、通过redis的复制功能可以很好的实现数据库的读写分离,提高服务器的负载能力。主数据库主要进行写操作,而从数据库负责读操作。

1:当一个从数据库启动时,会向主数据库发送sync命令,

2:主数据库接收到sync命令后会开始在后台保存快照(执行rdb操作),并将保存期间接收到的命令缓存起来

3:当快照完成后,redis会将快照文件和所有缓存的命令发送给从数据库。

4:从数据库收到后,会载入快照文件并执行收到的缓存的命令。

华为外包 2019年10月16日

1.spring cloud 的注册中心用的什么实现

三种技术实现是根据CAP理论(三种特性:Consistency(一致性) 、Availability(可用性)、Partition tolerance(分区容错性),在分布式设计中只能选其二)的取舍进行设计的,具体特性如下:

# eureka 是按照AP原则设计,作为分布式场景下的服务发现的产品较为合适,服务发现场景的可用性优先级较高,一致性并不是特别致命。各个服务可以单独提供服务,不需要发起选举;

# zookeeper 是按照CP原则设计,牺牲可用性,在服务发现场景并没太大优势,需要选举,在选举过程中服务不可用;

# Consul 是按照CA原则设计,为保证数据一致性,需要发起选举,在选举过程中服务不可用。

2.过滤器和拦截器区别和实现场景

拦截器 :是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。

过滤器:是在javaweb中,你传入的request、response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者 struts的action前统一设置字符集,或者去除掉一些非法字符.。

①拦截器是基于java的反射机制的,而过滤器是基于函数回调。

  ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。

  ③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。

  ④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。

  ⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。

1、日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。

2、权限检查:如登录检测,进入处理器检测检测是否登录,如果没有直接返回到登录页面;

3、性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);

4、通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现。

5、OpenSessionInView:如hibernate,在进入处理器打开Session,在完成后关闭Session。

3.sping boot的好处,在哪些方面可以提现

Spring 是一个“引擎”;

Spring MVC 是基于Spring的一个 MVC 框架;

Spring Boot 是基于Spring4的条件注册的一套快速开发整合包。

Spring Boot本身并不提供Spring框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于Spring框架的应用程序。也就是说,它并不是用来替代Spring的解决方案,而是和Spring框架紧密结合用于提升Spring开发者体验的工具。同时它集成了大量常用的第三方库配置(例如Jackson, JDBC, Mongo, Redis, Mail等等),Spring Boot应用中这些第三方库几乎可以零配置的开箱即用(out-of-the-box),大部分的Spring Boot应用都只需要非常少量的配置代码,开发者能够更加专注于业务逻辑。

Spring Boot只是承载者,辅助你简化项目搭建过程的。如果承载的是WEB项目,使用Spring MVC作为MVC框架,那么工作流程和你上面描述的是完全一样的,因为这部分工作是Spring MVC做的而不是Spring Boot。

对使用者来说,换用Spring Boot以后,项目初始化方法变了,配置文件变了,另外就是不需要单独安装Tomcat这类容器服务器了,maven打出jar包直接跑起来就是个网站,但你最核心的业务逻辑实现与业务流程实现没有任何变化。

5.垂直分表和水平分表,现实中的应用及问题

表分割有两种方式:  

  1水平分割:根据一列或多列数据的值把数据行放到两个独立的表中。

  水平分割通常在下面的情况下使用。

  •表很大,分割后可以降低在查询时需要读的数据和索引的页数,同时也降低了索引的层数,提高查询速度。

  •表中的数据本来就有独立性,例如表中分别记录各个地区的数据或不同时期的数据,特别是有些数据常用,而另外一些数据不常用。

  •需要把数据存放到多个介质上。

水平分割会给应用增加复杂度,它通常在查询时需要多个表名,查询所有数据需要union操作。在许多数据库应用中,这种复杂性会超过它带来的优点,因为只 要索引关键字不大,则在索引用于查询时,表中增加两到三倍数据量,查询时也就增加读一个索引层的磁盘次数。  

  2垂直分割:把主码和一些列放到一个表,然后把主码和另外的列放到另一个表中。

  如果一个表中某些列常用,而另外一些列不常用,则可以采用垂直分割,另外垂直分割可以使得数据行变小,一个数据页就能存放更多的数据,在查询时就会减少I/O次数。其缺点是需要管理冗余列,查询所有数据需要join操作

6.三个不同的书三位数加起来的,求他们的

7.继承和组合的区别

继承与组合都是面向对象中代码复用的方式。父类的内部细节对子类可见,其代码属于白盒式的复用,而组合中,对象之间的内部细节不可见,其代码属于黑盒式复用。继承在编码过程中就要指定具体的父类,其关系在编译期就确定,而组合的关系一般在运行时确定。继承强调的是is-a的关系,而组合强调的是has-a的关系。

8.git的常用命令,反向提交

9.redis的数据恢复

数据备份

save操作在Redis主线程中工作,因此会阻塞其他请求操作,应该避免使用。

bgSave则是调用Fork,产生子进程,父进程继续处理请求。子进程将数据写入临时文件,并在写完后,替换原有的.rdb文件。

数据恢复

CONFIG GET dir