中兴面经

1.设计模式六大设计原则

  1. 单一职责原则
    一个类,只有一个引起他变化的原因。
    如果一个类有多个引起他变化的职责,这些指责就会偶合在一起,当一个职责发生变化的后,会影响其他职责。
  2. 开放封闭原则
    对扩展是开放的,对修改是封闭的。
    对扩展开放,意味着有新的需求或变化的时候,可以对现有的代码进行扩展,以适应新的业务。
    对修改封闭,意味着一旦设计完成,就不能对类进行任何修改。
  3. 里氏替换原则
    子类可以扩展父类的功能,但不能改变父类原有的功能。
    包含四层含义:
    (1)子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
    (2)子类中可以增加自己特有的方法。
    (3)当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
    (4)当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。
  4. 最少知识原则
    核心思想是:低耦合、高内聚
    一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。
  5. 接口隔离原则
    对接口进行约束,尽量做到细化接口,但是细化接口会导致接口数量过多,所以要有限度;其次为实现接口的类只暴露这个类需要的放大,把不需要的隐藏。
  6. 依赖倒置原则
    核心思想是面向接口编程,不应该面向实现类编程。

2.TCP为什么可靠?

TCP保证可靠性的方式:

  • 连接管理
    三次握手建立连接和四次挥手断开连接,是保证可靠性的前提。
  • 确认应答机制与序列号
    TCP为传送的字节数据进行编号,这个就是序列号。
    当接收方接收到数据后,会对发送方进行确认应答。也就是发送一个ACK的报文,这个ACK报文中带有对应的确认序列号,告诉发送方,我已经接收到那些数据,下次发送数据需要从哪个地方发送。

情况1:数据包丢失的情况:
在这里插入图片描述
在特定的等待时间间隔内发送端主机还是没有收到来自接收端的确认应答,发送端就可以认为数据已经丢失了,并且进行重发处理。由此,即使产生了丢包也能够保证数据到达对端,实现可靠传输。

情况2:确认应答丢失的情况:
在这里插入图片描述
未收到对端的确认应答信号并不一定意味着数据包的丢失,也有可能是因为对端主机已经收到了该数据包,但是针对该数据包的确认应答包在回送途中丢失了而已,或者没有丢失、只是因为网络中的其他一些原因延迟很长时间才到达源主机。

此时,源主机只会按照重发机制重发数据包而已,但是这对于对端主机来说简直就是灾难,因为对端主机会反复接收到很多重复的不必要的数据,而为了对上层应用协议提供可靠的传输,对端主机不得不丢掉这些重复的数据包。因此,这对网络拥塞的形成造成了很大的促进。

所以,需要一种机制来识别是否已经接收到了这个数据包、又能够判断数据包是否需要接收。

序列号 是指按照顺序给发送数据包中的每一个字节都标识上号码编号,接收端主机 根据接收数据TCP包首部中的序列号和数据长度,来将自己下一步应该接收的序列号作为确认应答返送回去。就这样,根据序列号和确认应答信号,TCP可以实现可靠传输。
在这里插入图片描述

  • 流量控制
    如果发送端发送的数据太快,接收端的缓冲区被快速填充满。如果发送端继续以原有的速率发送数据,接收端会产生丢包,然后引起超时重传等情况。TCP会根据的接收端的数据处理能力,决定发送端的发送速度,这个机制就是流量控制。
    在TCP的报头中,有一个16位字段的窗口大小,这个窗口就是接收端剩余缓冲区的大小。接收端在确认应答发送ACK报文的时候,会将自己的窗口大小填入,随ACk报文一起发送。发送方可以根据报文里边的窗口大小的改变而随时调整自己的发送速度。如果窗口大小为零,那么发送方将停止发送,然后定期向接收方发送窗口探测数据段,让接收方把窗口大小告诉发送端。
    在这里插入图片描述
  • 拥塞控制
    核心是:慢启动,拥塞避免,快速重传,快速恢复
    (1)慢启动和拥塞避免
    TCP传输的过程中,如果网络可能处于拥堵状态,一开始就发送大量的数据,会加剧拥堵,大量丢包,严重影响传输。
    TCP引入慢启动的机制,在开始发送数据的时候,拥塞窗口设置为1,每次收到ACK应答,将窗口的值加1.在发送数据之前,将拥塞窗口与接收端反馈的窗口做对比,取较小的值作为实际发送窗口。
    随着数据包每次往返,用拥塞窗口会以1,2,4,8指数增长,为了控制增长,设置一个慢启动阈值,当窗口大小超过阈值时,窗口不以指数来增长,而是线性增长。在慢启动开始的时候,慢启动的阈值等于窗口的最大值,一旦造成网络拥塞,发生超时重传时,慢启动的阈值会为原来的一半(这里的原来指的是发生网络拥塞时拥塞窗口的大小),同时拥塞窗口重置为 1。
    在这里插入图片描述
    (2)滑动窗口与重发控制

引入滑动窗口之前,每发送一段数据,都需要等待接收方的确认应答ACK,才能继续发送下一段数据,如果数据丢失或者ACk应答信号丢失,需要超时重传。
但是引入滑动窗口窗口之后,可以连续发送多段数据,没有必要一直等待应答。

情况一:数据是已经被对端主机成功接收了的,但是应答信号丢失,是不需要进行重新发送的。然而,在没有使用窗口控制的前提下,没有收到确认应答包的数据包都会被重发。但是,在使用了窗口控制以后,就如图9 所示,某些应答包即使丢失了也无需重发,这也提高了传输效率。
在这里插入图片描述
情况2:数据包丢失的话,接收端接收到了一个自己需要的序列号之外的数据包,接收端会一直返回自己需要的序列号作为应答。
如果连续三次收到同一个应答,就会对数据进行重发,这种机制称为快速重发机制,比超时重发更加高效。
在这里插入图片描述

3.Redis中RDB和AOF两种持久化及其区别

  1. RDB原理(快照持久化)
    RDB是将数据库的快照以二进制的方式保存到磁盘中。
    redis父进程fork一个子进程,负责将内存中的内容写入到临时文件,而父进程继续处理client请求。基于操作系统的COW(copy on wite)机制,父子进程共享相同的物理页面,当父进程处理写请求的时候,os会为父进程修改的页面创建副本,在副本上修改。子进程将快照写入临时文件完毕后,用临时文件替换原来的快照文件。
    优点:
    (1)如果要进行大规模数据的恢复,RDB方式要比AOF方式恢复速度要快。
    (2)RDB可以最大化Redis性能,父进程做的就是fork子进程,然后继续接受客户端请求,让子进程负责持久化操作,父进程无需进行IO操作。
    (3)RDB是一个非常紧凑(compact)的文件,它保存了某个时间点的数据集,非常适合用作备份,同时也非常适合用作灾难性恢复,它只有一个文件,内容紧凑,通过备份原文件到本机外的其他主机上,一旦本机发生宕机,就能将备份文件复制到redis安装目录下,通过启用服务就能完成数据的恢复。
    缺点:
    (1)RDB这种持久化方式不太适应对数据完整性要求严格的情况,因为,尽管我们可以用过修改快照实现持久化的频率,但是要持久化的数据是一段时间内的整个数据集的状态,如果在还没有触发快照时,本机就宕机了,那么对数据库所做的写操作就随之而消失了并没有持久化本地dump.rdb文件中。
    (2)每次进行RDB时,父进程都会fork一个子进程,由子进程来进行实际的持久化操作,如果数据集庞大,那么fork出子进程的这个过程将是非常耗时的,就会出现服务器暂停客户端请求,将内存中的数据复制一份给子进程,让子进程进行持久化操作。
  2. AOF原理
    AOF 则以协议文本的方式,将所有对数据库进行过写入的命令(及其参数)记录到 AOF 文件,以此达到记录数据库状态的目的,只许追加文件不可改写文件,redis启动之后会读取appendonly.aof文件来实现重新恢复数据,完成恢复数据的工作。
    当然如果AOF 文件一直被追加,这就可能导致AOF文件过于庞大。因此,为了避免这种状况,Redis新增了重写机制,当AOF文件的大小超过所指定的阈值时,Redis会自动启用AOF文件的内容压缩,只保留可以恢复数据的最小指令集。
    优点:
    (1)AOF有着多种持久化策略:
    appendfsync always:每修改同步,每一次发生数据变更都会持久化到磁盘上,性能较差,但数据完整性较好;
    appendfsync everysec: 每秒同步,每秒内记录操作;
    appendfsync no:不同步。
    (2)Redis可以在AOF文件变得过大时,会自动地在后台对AOF进行重写:重写后的新的AOF文件包含了恢复当前数据集所需的最小命令集合。
    (3)AOF文件有序地保存了对数据库执行的所有写入操作。
    缺点:
    (1)对于相同的数据集来说,AOF文件要比RDB文件大。
    (2)根据所使用的持久化策略来说,AOF的速度要慢与RDB。一般情况下,每秒同步策略效果较好。不使用同步策略的情况下,AOF与RDB速度一样快。

4.java项目中VO和DTO以及Entity,各自是在什么情况下应用的?

1、entity 里的每一个字段,与数据库相对应;
2、vo 里的每一个字段,是和你前台 html 页面相对应;
3、dto 这是用来转换从 entity 到 vo,或者从 vo 到 entity 的中间的东西 。
dto 只是 entity 到 vo,或者 vo 到 entity 的中间过程。

5.spring ioc和aop

1、IOC

在平时的java应用开发中,我们要实现某一个功能或者说是完成某个业务逻辑时,至少需要两个对象合作,当一个对象依赖于另一个对象的时候,我们会使用new关键字创建一个对象,这个对象时我们程序员主动创建出来的,创建对象的主动权在自己手上,创建对象的时机也是我们自己控制的,这种方式,代码的耦合度比较高。

使用Spring之后,创建对象的工作是有Spring来完成的,Spring创建好对象之后放到容器中,当A对象需要B对象的时候,Spring将相应的B对象取出来,然后交给A对象使用,至于Spring是如何创建B对象的,啥时候创建的B对象,都是有Spring来控制。

IOC,控制反转就是说创建对象的控制权进行转移,以前创建对象的主动权在自己手中,现在将这种权利转移到了IOC容器。

1.IOC容器的工作机制:
在这里插入图片描述
第一步:通过XML配置文件,@Configuration注解的配置类或者@Autowired自动注入等配置Bean,读取这些Bean的配置信息,生成Bean配置注册表。
第二步:根据Bean配置注册表实例化bean,建立bean实例之间的依赖关系,并把Bean放在IOC容器的Bean缓存池中。
第三步:应用程序使用bean。

2.核心接口

  • BeanDefinition:主要用来描述Bean的定义,包括类型、属性、是否单例、是否懒加载、相关依赖等,Spring IOC容器在启动时会将我们在XML配置中或者注解的Bean解析成BeanDefinition,Spring IOC容器通过BeanDefinition对Bean进行管理和依赖装配。
  • BeanFactory:此接口是Spring IOC最底层核心接口,Spring IOC容器实现的架构基础,主要提供以下功能:
    提供IOC配置机制
    包含Bean的各种定义,便于实例化Bean
    建立Bean之间依赖关系
    Bean生命周期控制
  • ApplicationContext:建立在BeanFactory的基础之上,如果说BeanFactory是一辆汽车,那ApplicationContext就是一辆更高级的汽车拥有更多功能,它不仅仅拥有BeanFactory的能力,通过继承ResourceLoader、ApplicationEventPublisher等接口使它拥有加载资源文件和监听等能力。可以说BeanFactory构建了Spring IOC的基础,ApplicationContext在基础之上更进一步,其主要面向使用Spring的开发者。
    3.总结

总结一下Spring IOC容器初始流程基本如下:

  1. 创建BeanFactory
  2. 加载Bean信息,注册BeanDefinition到BeanFactory
  3. 通过BeanFactory的BeanDefinition注册信息实例化Bean实例
  4. 通过BeanFactory的BeanDefinition注册信息构建Bean之间依赖关系

2、AOP

在面向对象编程中,如果对多个不具有继承关系的对象引入一个公共的功能,会造成大量的代码冗余。AOP面向切面编程作为面向对象编程的一种补充,可以很好的解决这个问题,比如说要在系统中添加日志功能,每一个对数据修改的方法都要有这么一个日志记录功能,就可以利用AOP来增强。
AOP的一些概念
1.目标类(target):需要被增强的类。
2.连接点(Joinpoint):可能被增强的点,目标类中的所有方法。
3.切入点(Pointcut):将会被增强的连接点,目标类中被增强的方法。
4.通知/增强(Advice):对切入点增强的内容。增强的内容通常以方法的形式体现的。增强执行的位置不同,称呼不同。
(前置通知、后置通知、环绕通知、抛出异常通知、最终通知)通知方法所在的类,通常称为切面类。
5.切面(Aspect):通知和切入点的结合。一个通知对应一个切入点就形成一条线,多个通知对应多个切入点形成多条线,多条线形成了一个面,我们称为切面。
6.织入(Weaving): 生成切面并创建代理对象的过程。(将通知和切入点的结合,并创建代理对象的过程)
advice的时机有哪些?需要提供哪些接口?
这里直接拿Spring中定义好的增强的时机。

  • Before:在方法调用之前调用通知
  • After:在方法完成之后调用通知,无论方法执行成功与否
  • After-returning:在方法执行成功之后调用通知
  • After-throwing:在方法抛出异常后进行通知
  • Around:通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为

我们所说的Spring AOP,它包括基于XML配置的AOP和基于@AspcetJ注解的AOP,这两种方法虽然在配置切面时的表现方式不同,但底层都是使用动态代理技术(JDK代理或CGLib代理)。

Spring可以继承AspcetJ,但AspcetJ本身并不属于Spring AOP的范畴:

  • AspectJ:
    AspectJ 在编译时“自动”编译得到了一个新类,这个新类增强了原有的 类的功能,因此 AspectJ 通常被称为编译时增强的 AOP 框架、
  • Spring AOP:
    与 AspectJ 相对的还有另外一种 AOP 框架,它们不需要在编译时对目标类进行增强,而是运行时生成目标类的代理类,该代理类要么与目标类实现相同的接口,要么是目标类的子类——总之,代理类的实例可作为目标类的实例来使用。

Spring 允许使用 AspectJ Annotation 用于定义方面(Aspect)、切入点(Pointcut)和增强处理(Advice),Spring 框架则可识别并根据这些 Annotation 来生成 AOP 代理。Spring 只是使用了和 AspectJ 5 一样的注解,但并没有使用 AspectJ 的编译器或者织入器(Weaver),底层依然使用的是 Spring AOP,依然是在运行时动态生成 AOP 代理,并不依赖于 AspectJ 的编译器或者织入器。

简单地说,Spring 依然采用运行时生成动态代理的方式来增强目标对象,所以它不需要增加额外的编译,也不需要 AspectJ 的织入器支持;而 AspectJ 在采用编译时增强,所以 AspectJ 需要使用自己的编译器来编译 Java 文件,还需要织入器。

Spring AOP and AspectJ AOP 有什么区别?AOP 有哪些实现方式?
AOP实现的关键在于 代理模式,AOP代理主要分为静态代理和动态代理。静态代理的代表为AspectJ;动态代理则以Spring AOP为代表。
(1)AspectJ是静态代理的增强,所谓静态代理,就是AOP框架会在编译阶段生成AOP代理类,因此也称为编译时增强,他会在编译阶段将AspectJ(切面)织入到Java字节码中,运行的时候就是增强之后的AOP对象。
(2)Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。

CGLib代理与JDK动态代理:

1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP
3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换

6.final finally finalize 区别

  • final是关键字。用来修饰类,类不可以被继承;修饰方法,方法不可以被子类重写;修饰变量,如果是基本数据类型,不可以改变,如果是引用数据类型,引用的地址不可以改变。
  • finally
    提到finally,那么try-catch就逃不掉了。finally 则是Java保证重点代码一定要被执行的一种机制。最常用的地方:通过try-catch-finally来进行类似资源释放、保证解锁等动作。
  • finalize
    finalize()为方法,在CG要回收某个对象时,finalize()方法是在垃圾收集器删除对象之前对这个对象调用的,如果在这期间对象与GCROOTS引用连建立了联系,他会逃逸,避免被垃圾回收器回收。

7.mybatis

1.MyBatis的作用?

MyBatis是持久层框架,支持JDBC的,简化了持久层开发!
使用MyBatis时,只需要通过接口指定数据操作的抽象方法,然后配置与之关联的SQL语句,即可完成!

2、mybatis中的#和$的区别?

  • #{}将传入的数据当做字符串来处理,会对传进来的数据自动加“”,这种方式可以很大程度上防止SQL注入。
  • ${}会将传进来的参数直接显示在生成的SQL中,直接参与SQL的编译,无法防止SQL注入。
    但是涉及到动态的表名和列名的时候不能不使用这种方式,需要我们手工做好过滤工作,方式SQL注入。

3、什么是SQL注入?

攻击者在URL上或者表单信息中输入一些有害的SQL片段,入侵程序。
在银行软件这种要求性较高的场景下,经常将SQL语句转存为存储过程这样的方式,来防止SQL注入。

4、mybatis是如何做到防止sql注入的?

因为MyBatis底层使用的是JDBC中的PreparedStatement类,对SQL语句进行预编译。带传入的参数使用占位符“?”代替。执行时,直接使用编译好的SQL,替换占位符“?”就可以了。因为SQL注入只能对编译过程起作用,所以这样的方式就很好地避免了SQL注入的问题.

8.为什么需要缓存?

最终目的:高并发,高性能。

在实际的业务中,有一些查询操作非常耗时,并且查询的结果并不怎么变化,但是有很高的请求量,可以直接将查询出来的结果存放在内存中,后面直接读缓存就可以了。

缓存带来的不良影响:

  • 缓存与数据库不一致
  • 缓存穿透和缓存雪崩
  • 缓存并发竞争

9. 面向对象的特点

  • 封装
  • 继承
  • 多态

10.Linux用过哪些命令?

yum install 现在安装
chmod -R 777 filename 修改文件权限 r表示读、w表示写、x表示可执行
top 命令经常用来监控linux的系统状况,比如cpu、内存的使用
gcc 编译c语言源文件
vim 编辑文本
ps –ef | grep tomcat 查看所有有关tomcat的进程
tar -xvzf test.tar.gz 解压文件解压文件
tail -f exmaple.log 查看日志文件

11.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值