初次面试~蚂蚁金服

1、Java面向对象具有哪些特点

四大特征:抽象、封装、继承、多态

2、用伪代码描述多态的具体过程,为什么要有不同的行为描述,这种不同的行为状态有什么好处

【我感觉面试官在问这个问题的时候,意思就是多态的优势。】

多态是指允许不同类的对象对同一消息作出响应,使用多态的语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。多态有两种表现形式:重载和重写。

3、大概介绍一下重写和重载

首先说重载(overload),是发生在同一个类中。与什么父类子类、继承毫无关系。标识一个函数除了函数名外,还有函数的参数(个数和类型)。也就是说,一个类中可以有两个或更多的函数,叫同一个名字而他们的参数不同。 他们之间毫无关系,是不同的函数,只是可能他们的功能类似,所以才命名一样,增加可读性,仅此而已!
再说重写(override),是发生在子类中!也就是说必须有继承的情况下才有覆盖发生。我们知道继承一个类,也就有了父类了全部方法,如果你感到哪个方法不爽,功能要变,那就把那个函数在子类中重新实现一遍。 这样再调用这个方法的时候,就是执行子类中的过程了。父类中的函数就被覆盖了。(当然,覆盖的时候函数名和参数要和父类中完全一样,不然你的方法对父类中的方法就不起任何作用,因为两者是两个函数,毫不关系)

4、Java常用的框架spring有什么了解

我当时坦白说:这个还没有学到,面试官直接跳过。

5、为什么Java可以做到跨平台运行

因为JAVA有个属于自己的运行环境,既:JAVA虚拟机,虚拟机与平台无关,JAVA代码经过编译后,直接运行于虚拟机上,实现了跨平台。

6、C或者C++在运行的时候去申请一块内存,开发程序人员需要自己去管理这块内存,Java编程自己去申请资源或者定义对象的时候,不需要自己去释放资源,为什么Java可以不需要自己释放资源

我当时回答的是Java具有垃圾回收机制,然后就有了下一个问题。【感觉自己给自己挖了一个坑】

7、有没有了解过垃圾回收机制的原理

这个目前还没有学到。

8、可以简单介绍一下TCP和UDP之间的区别

TCP 是面向连接的、可靠的流协议。流就是指不间断的数据结构,当应用程序采用 TCP 发送消息时,虽然可以保证发送的顺序,但还是犹如没有任何间隔的数据流发送给接收端。TCP 为提供可靠性传输。

UDP 是不具有可靠性的数据报协议。细微的处理它会交给上层的应用去完成。在 UDP 的情况下,虽然可以确保发送消息的大小,却不能保证消息一定会到达。

TCP 和 UDP 的优缺点无法简单地、绝对地去做比较:TCP 用于在传输层有必要实现可靠传输的情况;而在一方面,UDP 主要用于那些对高速传输和实时性有较高要求的通信或广播通信。

9、TCP为什么是可靠的传输

1)、数据可以完全到达接收方   应答确认机制(ack)和超时重传机制
2)、接收方数据是有序的 每一个TCP报文段都有序号
3)、数据发送和接收保证完全一致 TCP首部有16位校验码 

10、假设有一个客户端发送了一个报文段到服务端,那么假设中间遇到了一些网络故障,客户端是如何确定我需要进行重传,客户端如何确定对方有没有收到消息,假设三次握手已经成功

【ACK机制】TCP报文的重传机制是由设置的超时定时器来决定的,在定时的时间内没有收到确认信息,则进行重传。

11、BIO和NIO之间的区别

BIO同步阻塞:服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,可以通过线程池机制改善。

BIO模式,需要先在服务端启动一个ServerSocket,然后在客户端启动Socket来对服务端进行通信,默认情况下服务端需要对每个请求建立一堆线程等待请求,而客户端发送请求后,先咨询服务端是否有线程相应,如果没有则会一直等待或者遭到拒绝请求,如果有的话,客户端会线程会等待请求结束后才继续执行。

NIO同步非阻塞的:服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。

NIO目的是解决的是BIO的大并发问题,也就是说,将每一个客户端请求分配给一个线程来单独处理。这样做虽然可以达到我们的要求,但同时又会带来另外一个问题。由于每创建一个线程,就要为这个线程分配一定的内存空间,而且操作系统本身也对线程的总数有一定的限制。如果客户端的请求过多,服务端程序可能会因为不堪重负而拒绝客户端的请求,甚至服务器可能会因此而瘫痪。

NIO的最重要的地方是当一个连接创建后,不需要对应一个线程,这个连接会被注册到多路复用器上面,所以所有的连接只需要一个线程就可以搞定,当这个线程中的多路复用器进行轮询的时候,发现连接上有请求的话,才开启一个线程进行处理,也就是一个请求一个线程模式。

BIO与NIO一个比较重要的不同,是我们使用BIO的时候往往会引入多线程,每个连接一个单独的线程;而NIO则是使用单线程或者只使用少量的多线程,每个连接共用一个线程。

12、在这样一个情境下,假设我的CPU使用率没有达到最大,NIO只是用一个线程或者简单的线程来处理多个用户的请求,BIO是一个连接一个线程,那么NIO的性能还优于BIO吗?为什么NIO优于BIO

这个问题的话,我觉得在不同的情境下,BIO和NIO都是各有优势的。

13、用伪代码简单叙述一下NIO和BIO如何创建客户端和服务端

NIO服务端:

1、初始化ServerSocketChannel并且绑定端口

2、实例化选择器Selector,将ServerSocketChannel设置为非阻塞并注册到选择器中,并关注ACCEPt事件

3、选择器调用select,监听事件是否发生

4、选择器上事件发生,则进行感兴趣集合遍历,找到ACCEPT事件

5、调用Accept方法,获取新的连接通道SocketChanel,将该通道设置为非阻塞并注册到选择器上,关注READ事件

6、继续调用select,监听读事件是否发生

7、读事件发生、则进行SocketChanel通道读取,读取完成关闭SocketChanel通道

8、关闭选择器Selector、关闭通道ServerSocketChannel

客户端:

1、初始化SocketChanel实例,并设置为非阻塞状态

2、实例化选择器Selector

3、SocketChanel通道尝试连接(Connect)服务端,未连接成功则将通道注册到选择器,并关注CONNECT事件

4、选择器调用select,监听连接事件是否发生

5、连接事件发生、则完成信道连接(SocketChanel.finshConnect),发送消息,并注册READ事件

5、可读事件发生,读取数据

6、数据读取完成,关闭Selector、SocketChanel

BIO客户端:

1、初始化ServerSocket并且绑定端口号

2、使用accept()方法连接服务端

3、IO操作

4、关闭操作

服务端

1、创建客户端socket实例

2、使用connect()方法建立客户端创建和服务端的连接

3、IO操作

4、关闭操作

14、线程池的参数设置以及其执行流程

1)、corePoolSize:线程池的核心线程数量

2)、maximumPoolSize:线程池中允许的最大线程数量

3)、keepAliveTime:线程空闲时的存活时间

4)、TimeUnit unit:keepAliveTime的单位

5)、workQueue:workQueue必须是BlockingQueue阻塞队列

6)、threadFactory:创建线程的工厂

7)、RejectedExecutionHandler:饱和策略

执行流程:

(1)如果线程池中的线程数量少于corePoolSize,就创建新的线程来执行新添加的任务;

(2)如果线程池中的线程数量大于等于corePoolSize,但队列workQueue未满,则将新添加的任务放到workQueue中,按照FIFO的原则依次等待执行(线程池中有线程空闲出来后依次将队列中的任务交付给空闲的线程执行);

(3)如果线程池中的线程数量大于等于corePoolSize,且队列workQueue已满,但线程池中的线程数量小于maximumPoolSize,则会创建新的线程来处理被添加的任务;

(4)如果线程池中的线程数量等于了maximumPoolSize,就用RejectedExecutionHandler来做拒绝处理
【如果线程池中的线程数量满了,队列也存储满了,该如何处理:我当时就回答的是使用饱和策略的--->用调用者所在线程来执行任务,面试官恩了一声,我觉得他的意思是想让在这种情况下,能够有线程来处理】

15、数据库了解过吧,有没有具体使用过MySQL

这个目前还没有学到,稍后会更新在我的博客里面。

16、并发、同步、死锁(具体问的什么想不起来了)

关于这个更新在我的下一篇博客里面。

17、开放题:双十一的时候,在零点的时候,交易量很大,访问量很大,有没有想过阿里在这种情况下是如何具体处理的

1)、HTML静态化

如果网站的请求量过大,我们可以将页面静态化提供访问来缓解服务器压力,能够缓解服务器压力加大以及降低数据库数据的频繁交换。适合于某些访问了过大,但是内容不经常改变的页面,如首页等。

2)、文件服务器

文件服务器就是将文件系统单独拿出来提供专注于处理文件的存储访问系统。因为对于图片这种资源的访问存储是web服务最耗资源的地方,将文件服务器单独部署既可以将压力转移,交给专门的系统处理,又可以分担风险,如果图片服务器出现问题,那么主服务器能够保证正常,顶多就是文件请求不到。

3)、负载均衡

负载均衡将是大型网站解决高负荷访问和大量并发请求采用的终极解决办法。

负载均衡建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。其原理就是将大量工作分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。

软件负载均衡:解决方案是指在一台或多台服务器相应的操作系统上安装一个或多个附加软件来实现负载均衡。

软件解决方案缺点也较多,因为每台服务器上安装额外的软件运行会消耗系统不定量的资源,越是功能强大的模块,消耗得越多,所以当连接请求特别大的时候,软件本身会成为服务器工作成败的一个关键;软件可扩展性并不是很好,受到操作系统的限制;由于操作系统本身的Bug,往往会引起安全问题。

硬件负载均衡:解决方案是直接在服务器和外部网络间安装负载均衡设备,这种设备通常称之为负载均衡器,由于专门的设备完成专门的任务,独立于操作系统,整体性能得到大量提高,加上多样化的负载均衡策略,智能化的流量管理,可达到最佳的负载均衡需求。

一般而言,硬件负载均衡在功能、性能上优于软件方式,不过成本昂贵。

负载均衡从其应用的地理结构上分为本地负载均衡(Local Load Balance)和全局负载均衡(Global Load Balance,也叫地域负载均衡)

本地负载均衡是指对本地的服务器群做负载均衡,能有效地解决数据流量过大、网络负荷过重的问题,并且不需花费昂贵开支购置性能卓越的服务器,充分利用现有设备,避免服务器单点故障造成数据流量的损失。其有灵活多样的均衡策略把数据流量合理地分配给服务器群内的服务器共同负担。即使是再给现有服务器扩充升级,也只是简单地增加一个新的服务器到服务群中,而不需改变现有网络结构、停止现有的服务。

全局负载均衡是指对分别放置在不同的地理位置、有不同网络结构的服务器群间作负载均衡,全局负载均衡主要用于在一个多区域拥有自己服务器的站点,为了使全球用户只以一个IP地址或域名就能访问到离自己最近的服务器,从而获得最快的访问速度。

4)动静分离:所谓动静分离就是将网站静态资源(HTML,JavaScript,CSS,img等文件)与后台应用分开部署,提高用户访问静态代码的速度,降低对后台应用访问。

5)缓存:缓存可以让我们将一些有时效性的、经常访问的、不便于存储数据库等的数据,将数据存储在专门的用于缓存的应用程序中,如果有必要,还可以将缓存应用服务器单独部署,如果数据量过大,我们还可以组成缓存服务器集群,比如:cache、redis等都是比较专注于缓存数据的。

6)数据库读写分离:读写分离简单的说是把对数据库读和写的操作分开对应不同的数据库服务器,这样能有效地减轻数据库压力,也能减轻io压力。主数据库提供写操作,从数据库提供读操作。

7)批量读取和延迟修改:高并发情况可以将多个查询请求合并到一个。同一查询,同一返回处理,降低短时间内的数据库请求数量。高并发且频繁修改的可以暂存缓存中,然后统一进行修改。

8)数据库集群和库表散列:通常对于一个服务器的处理的瓶颈大多在于数据库的瓶颈,对于大数据量的请求处理,单个数据库处理能力有限,所以我们可以部署多个数据库,然后将数据库组成一个集群。

猜你喜欢

转载自blog.csdn.net/qq_40303781/article/details/88536576