收集的面试题 二

收集的面试题 二,第1张

收集的面试题 二 十一 1、Redis是什么,怎么持久化

Redis是一个高性能的内存数据库,以key-value方式存储数据,可以作为缓存使用。

Redis支持RDB和AOF两种持久化机制。持久化功能有效地避免因进程退出造成的数据丢失问题,下次重启时利用之前持久化的文件即可实现数据恢复。

RDB:RDB持久化是把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化过程分为手动触发和自动触发。

触发机制

   手动触发分别对应save和bgsave命令

   save命令:阻塞当前Redis服务器,知道RDB过程完成为止,对于内存比较大的实例会造成长时间阻塞,线上不建议使用。

    DB saved on disk

    bgseve命令:Redis进程执行fork *** 作创建子进程,RDB持久化过程有子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。

        * Background saving started by pid 3151

        * DB saved on disk

        * RDB: 0 MB of memory used by copy-on-write

        * Background saving terminated with success

自动触发

        以下场景下会触发

       1)使用save相关配置,如“save m n”。表示m秒内数据集存在n次修改时,自动触发bgsave。

       2)如果从节点执行全量复制 *** 作,主节点自动执行bgsave生成RDB文件并发送给从节点,更多细节见6.3节介绍的复制原理。

       3)执行debug reload命令重新加载Redis时,也会自动触发save *** 作。

       4)默认情况下执行shutdown命令时,如果没有开启AOF持久化功能则自动执行bgsave。

2、为什么使用elasticsearch

Elasticsearch具备以下特点:

        分布式,无需人工搭建集群

        Restful风格,一切API都遵循Rest原则,容易上手

        近实时搜索,数据更新在Elasticsearch中几乎是完全同步的。

正排索引

        通过key找到value,如通过id找到文章

        查询内容时,需要逐条遍历,速度比较慢

倒排索引

        通过value找到key

        对内容进行分词,生成倒排索引

3、rabbitMQ的工作模式

工作队列,生产者将消息分发给多个消费者,如果生产者生产了100条消息,消费者1消费50条,消费者2消费50条,队列发送消息采用的是轮询方式,也就是先发给消费者1,再发给消费者2,依次往复。

因为队列默认采用是自动确认机制,消息发过去后就自动确认,队列不清楚每个消息具体什么时间处理完,所以平均分配消息数量。

实现能者多劳:

channel.basicQos(1);限制队列一次发一个消息给消费者,等消费者有了反馈,再发下一条

channel.basicAck 消费完消息后手动反馈,处理快的消费者就能处理更多消息

basicConsume 中的参数改为false

4、mysql的连接方式左连接和右连接是什么概念

left join

显示所有左表的数据,加上右表相关的数据,不相关的补空值

right join

显示所有右表的数据,加上左表相关的数据,不相关的补空值

5、代码连接mysql的工具是什么,mybatis的sql语句放在哪

JDBC,mybatis的sql语句可以写在mapper文件中,也可以通过注解写在dao层的方法上

6、单点登录怎么实现

登录成功后,将用户信息用JWT+RSA算法进行加密,保存到请求头中

在网关中添加全局过滤器,对请求进行拦截,获得请求头中的token,进行解码,成功就放行

7、gateway服务怎么跳转到别的服务的,普通用户登录后怎么访问的页面

    客户端发送请求给Gateway网关,网关将请求发送给处理器映射(HandlerMapping)

    网关通过路由的匹配,将请求发送给Web处理器处理,请求就需要经过一系列过滤器

    过滤器分为“pre"前置和”post"后置两种,前置过滤器实现鉴权作用,后置过滤实现性能统计或日志收集

    通过过滤器到达需要的服务

8、webSocket怎么实现传到前台的,还有什么其他方式吗
    websocket允许通过Javascript建立远程服务器的连接,从而实现客户端与服务器间的双向通信,在websocket中有两个方法
    1.send()向远程服务器发送数据
    2.close()关闭websocket连接
    websocket同时还定义了几个监听函数    
        1、onopen 当网络连接建立时触发该事件
        2、onerror 当网络发生错误时触发该事件
        3、onclose 当websocket被关闭时触发该事件
        4、onmessage 当websocket接收到服务器发来的消息的时触发的事件,也是通信中最重要的一个监听事件。msg.data
    websocket还定义了一个readyState属性,这个属性可以返回websocket所处的状态:
        1、ConNECTING(0) websocket正尝试与服务器建立连接
        2、OPEN(1) websocket与服务器已经建立连接
        3、CLOSING(2) websocket正在关闭与服务器的连接
        4、CLOSED(3) websocket已经关闭了与服务器的连接

websocket的url开头是ws,如果需要ssl加密可以使用wss,当我们调用websocket的构造方法构建一个websocket对象(new WebSocket(url))的之后,就可以进行即时通信了。

10、seata用到了吗,怎么实现的

Seata的分布式事务解决方案是业务层面的解决方案,只依赖于单台数据库的事务能力。Seata框架中一个分布式事务包含3中角色:

Transaction Coordinator (TC): 事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚。

Transaction Manager (TM): 控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议。

Resource Manager (RM): 控制分支事务,负责分支注册、状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚。

其中,TM是一个分布式事务的发起者和终结者,TC负责维护分布式事务的运行状态,而RM则负责本地事务的运行。

首先TM 向 TC 申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的 XID。

XID 在微服务调用链路的上下文中传播。

RM 开始执行这个分支事务,RM首先解析这条SQL语句,生成对应的UNDO_LOG记录。下面是一条UNDO_LOG中的记录

RM在同一个本地事务中执行业务SQL和UNDO_LOG数据的插入。在提交这个本地事务前,RM会向TC申请关于这条记录的全局锁。如果申请不到,则说明有其他事务也在对这条记录进行 *** 作,因此它会在一段时间内重试,重试失败则回滚本地事务,并向TC汇报本地事务执行失败

RM在事务提交前,申请到了相关记录的全局锁,因此直接提交本地事务,并向TC汇报本地事务执行成功。此时全局锁并没有释放,全局锁的释放取决于二阶段是提交命令还是回滚命令。

TC根据所有的分支事务执行结果,向RM下发提交或回滚命令。

RM如果收到TC的提交命令,首先立即释放相关记录的全局锁,然后把提交请求放入一个异步任务的队列中,马上返回提交成功的结果给 TC。异步队列中的提交请求真正执行时,只是删除相应 UNDO LOG 记录而已。

在at模式中需要在客户端的数据库中建如下的表,用来保存回滚的数据

seata的数据源代理通过对业务sql的解析,在业务sql执行前后生成前置镜像和后置镜像保存在undo_log中,业务sql的执行和undo_log的插入在一个本地事务中,这样就可以保证任何对业务数据的更新都有相应的回滚日志存在。

在本地事务提交之前还会构建lockKey(本次事务提交影响的数据,lockKey的构建规则之前的文章已经说过了哈),向TC对涉及到的数据加锁,当加锁成功后,才会执行本地事务的commit过程,如果加锁失败,RM会根据重试策略进行重试,如果重试也失败,那么回滚本地事务

当TM向TC发起全局提交请求时,此时分支事务实际上以及提交了,TC立即释放该全局事务的锁,然后异步调用RM清理回滚日志

十二 1、SpringSecurity的使用流程,具体到代码

安全框架,能够帮助实现权限控制,不同的用户能查看或 *** 作不同的资源。

主流的安全框架:

    Shiro SSM配置少,容易上手

    SpringSecurity SpringBoot整合配置较少,强大

SpringSecurity是一个强大且高效的安全框架,能够提供用户验证和访问控制服务,能够很好地整合到以Spring为基础的项目中。 SpringBoot对SpringSecurity进行了大量的自动配置,使开发者通过少量的代码和配置就能完成很强大的验证和授权功能。

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //在内存中创建用户
        auth.inMemoryAuthentication()
                //账号
                .withUser("admin")
                //密码,需要加密
                .password(new BCryptPasswordEncoder().encode("123"))
                //添加角色
                .roles("ADMIN","USER")
                //创建另一个用户
                .and()
                .withUser("user")
                .password(new BCryptPasswordEncoder().encode("123"))
                .roles("USER");
    }

    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //用户请求授权
        http.authorizeRequests()
                //指定登录相关的请求,permitAll是不需要验证
                .antMatchers("/login").permitAll()
                //指定/user/** 需要USER角色
                .antMatchers("/user/**").hasRole("USER")
                .antMatchers("/admin/**").hasRole("ADMIN")
                //其它所有URL都需要验证
                .anyRequest().authenticated()
                .and()
                //配置登录URL为login,登录成功后跳转main
                .formLogin().loginPage("/login").defaultSuccessUrl("/main")
                .and()
                //配置注销url,注销后到登录页面
                .logout().logoutUrl("/logout").logoutSuccessUrl("/login");
    }
}
3、SpringMVC的执行流程 4、elasticsearch的使用流程 5、ssm对数据库表进行增删改查的具体流程 十三 1、单点登录除了用JWT和RSA之外,还有什么方法实现,为什么要用JWT和RSA

实现方式一:父域 cookie

cookie 的作用域由 domain 属性和 path 属性共同决定。

domain 属性的有效值为当前域或其父域的域名/IP地址,在 Tomcat 中,domain 属性默认为当前域的域名/IP地址。path 属性的有效值是以“/”开头的路径,在 Tomcat 中,path 属性默认为当前 Web 应用的上下文路径。

如果将 cookie 的 domain 属性设置为当前域的父域,那么就认为它是父域 cookie。cookie 有一个特点,即父域中的 cookie 被子域所共享,换言之,子域会自动继承父域中的cookie。

利用 cookie 的这个特点,不难想到,将 Session ID(或 Token)保存到父域中不就行了。没错,我们只需要将 cookie 的 domain 属性设置为父域的域名(主域名),同时将 cookie 的 path 属性设置为根路径,这样所有的子域应用就都可以访问到这个 cookie 了。

不过这要求应用系统的域名需建立在一个共同的主域名之下,如 tieba.baidu.com 和 map.baidu.com,它们都建立在 baidu.com 这个主域名之下,那么它们就可以通过这种方式来实现单点登录。

使用JWT&RSA实现单点登录,通过RSA对公钥和私钥字符串进一步处理,JWT生成Token时,使用公钥进行加密,解析时,JWT通过私钥对Token进行解析(token可以设置过期时间,如果token过期,会自动解析失败)

2、SpringBoot的事物怎么配置

在spring配置文件中添加事务管理的配置



   
   


在需要事务的Service方法上添加注解:
@Transactional

3、SpringCloud的组件了解多少

主要的组件:

        注册中心,服务的注册和发现机制,Eureka、Nacos、Zookeeper等

        配置中心,集中管理服务的配置文件,Config、Nacos

        API网关,实现路由和权限管理,Zuul、Gateway

        服务通信,实现Restful的服务调用,Openfeign、Dubbo

        负载均衡,平衡每个服务的负载量,Ribbon

        熔断器,提高系统的可靠性,Hystrix、Sentinel

        分布式事务,全局事务管理多个服务,Seata

4、SpringMVC的执行流程 5、mybatis中#和$的区别 6、事物是不是只要出现异常就一定会回滚

默认情况下,出现 RuntimeException(运行时异常)或 Error 的时候,Spring 才会回滚事务。

如果在代码中对异常进行了try catch *** 作使得RuntimeException或 Error 没有抛出来,此时事务业务不会回滚

7、es用的什么分词器

Lucene的IK分词器早在2012年已经没有维护了,现在我们要使用的是在其基础上维护升级的版本,并且开发为Elasticsearch的集成插件了,与Elasticsearch一起维护升级,版本也保持一致

8、关系型数据库事务有ACID四大特征,其中有一项为隔离性,请简述MySQL数据库支持的隔离级别

Mysql的四种隔离级别
SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。

Read Uncommitted(读取未提交内容)

在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。

Read Committed(读取提交内容)

这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。

Repeatable Read(可重读)

这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。

Serializable(可串行化)

这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。

9、简述Spring框架中IOC特征是什么意思

IOC(Inverse of Control)控制反转是一种程序设计思想。

控制JavaBean(Java对象)的创建和管理

反转是,一般情况下对象的创建和管理由开发者控制,反转是把对象的创建和管理交给容器完成,然后再交给开发者。

10、浏览器访问www.taobao.com经历了怎样的过程

利用DNS协议进行域名解析   -->   建立tcp协议三次握手过程   -->   客户端发出访问网站相应页面请求(发出http协议请求报文)   -->   服务端发出相应访问页面的请求信息(发出http)   -->   断开tcp协议四次挥手过程

十四 1、java容器 2、说说你的这个权限功能怎么实现的,用了哪些技术

通过SpringSecurity进行登录验证,查询该用户对应的权限,管理员可以给不同的用户赋予不同的角色,角色对应相应的权限。

Mybatis  SpringSecurity SpringBoot

4、String常用方法 5、怎么实现字符串的反转

1、通过StringBuiler的reverse()的方法

2、  通过String的 toCharArray()方法可以获得字符串中的每一个字符串并转换为字符数组,然后用一个空的字符串从后向前一个个的拼接成新的字符串。

7、消息的队列出现异常怎么处理的

由于网络、软硬件等问题,消息是存在丢失问题的

在哪几个方面存在丢失:

    生产者到交换机

    交换机到队列

    队列到消费者

解决方案:

    针对 生产者到交换机

    confirm 机制 确定生产者将消息投递到交换机

      针对 交换机到队列

    return 机制 交换机发送消息到队列失败会执行回调

      针对 队列到消费者

    消息没发 --> 消息持久化

    消息发了,不知道是否被消费 ---> 手动确认 ack

rabbitmq:
  publisher-/confirm/i-type: correlated  # 启动/confirm/i机制
  publisher-returns: true # 启动return机制

重复消费问题:

队列发送消息给消费者,因为网络原因,消费者没有收到,队列重复发送,网络恢复后会发送多个相同的消息给消费者

可能导致问题:

重复添加数据等非幂等性业务问题

非幂等性业务(每次 *** 作获得不同结果,如:添加)

幂等性业务(每次 *** 作结果相同,如:更新、删除)

消息有唯一id,保存redis,手动确认

解决方案:

    给每个消息添加id

    消费者获得消息后,通过id查询redis,判断该id是否存在

    如果不存在,就修改该id的value为1,执行业务,进行手动确认

    如果存在,就不执行业务

Redis的setnx命令

setnx key value

如果该键不存在,就设置键和值,返回1

如果该键存在,直接返回

十五 1、什么是字段和属性

字段又称为:“成员变量”,一般在类的内部做数据交互使用
字段命名规范:camel命名法(首单词字母小写)

私有化: 字段就好比我们的个人财产,仅供个人使用,所以一般是private修饰。
添加标准: 根据程序的功能需求,具体来添加需要的不同类型的字段。

硬编码: 类中的静态字段,外部无法修改
比如使用 const关键字

const: 静态常量,是编译时常量,const较高效
readonly: 动态常量,是运行时常量,readonly较灵活

1.const默认是静态的,只能由类型来访问,不能与static同时使用;readonly默认是非静态的,由实例对象来访问,可以显示使用static定义为静态成员;

2.const只能应用在值类型和string类型上,其他引用类型常量只能定义为null,否则以new为const引用类型常量赋值,;readonly只读字段,可以使任意类型,但是对于引用类型字段来说,readonly不能限制对该对象实例成员的读写控制;编译器会引发“只能用null对引用类型(字符串除外)的常量进行初始化“的错误提示;

3.const必须在字段声明时初始化;readonly可以再声明时,或者构造函数中进行初始化,不同的构造函数可以为readonly常量实现不同的初始值;

4.const可以定义字段和局部变量;而readonly则只能定义字段;static readonly的初始化,必须在定义时,或者静态无参构造函数中进行;

5.数组和结构体不能被声明为const常量,string类型可以被声明为常量,因为string类型的字符串恒定特性,使得string的值具有只读特性;

属性其实就是外界访问私有字段的入口,属性本身不保存任何数据,在对属性赋值和读取的时候其实就是 *** 作的对应私有字段。

属性本质其实就是一个方法,通过get和set方法来 *** 作对应的字段

2、产品的开发阶段有几个,作用是什么

    可行性分析(市场、技术、社会)

    项目立项(启动大会,确定项目周期、团队、管理者)

    需求分析(确定项目功能、界面等)

    概要设计(架构设计、技术选型、数据库设计)

    详细设计(具体功能设计、接口设计、数据库设计)

    项目开发(数据库表的创建、代码的编写)

    测试

    上线

    运维

3、序列化和反序列化的应用场景

主要用于存储对象状态为另一种通用格式,比如存储为二进制、xml、json等等,把对象转换成这种格式就叫序列化,而反序列化通常是从这种格式转换回来。
使用序列化主要是因为跨平台和对象存储的需求,因为网络上只允许字符串或者二进制格式,而文件需要使用二进制流格式,如果想把一个内存中的对象存储下来就必须使用序列化转换为xml(字符串)、json(字符串)或二进制(流)

4、你熟悉的页面传值的方式

1.参数直接绑定 直接定义和表单元素name相同的参数

2.@RequestParam注解绑定参数 如果名称不一样,可以通过@RequestParam注解配置参数

3.对象绑定参数 通过对象也可以进行参数绑定

4.@PathVariable绑定参数 /login/{username}/{password} @PathVariable("username")String username,……

通过URL的路径也可以实现参数绑定 在URL中可以使用{name}来定位参数的位置,name是@PathVariable注解中配置的名称

5.通过Map集合进行参数绑定

6.通过List集合进行参数绑定

7.HttpServlet

5、什么是事件委托

事件代理又称事件委托,是javascript中绑定事件的常用技巧。顾名思义,‘事件代理’就是把原本需要绑定的事件委托给父元素,让父元素负责事件监听。事件代理的原理是DOM元素的事件冒泡。使用事件代理的好处是可以提高性能

事件委托的好处:
1.减少事件数量,提高性能
2.预测未来元素,新添加的元素仍然可以触发该事件
3.避免内存外泄,在低版本的IE中,防止删除元素而没有移除事件而造成的内存溢出

7、什么是存储过程,有什么优点?

Stored Procedure 封装一系列SQL指令,编译后保存在数据库中,可以传递参数并进行调用。

优点:

    执行效率高(存储过程已经编译过,直接调用)

    安全性高(网络中不需要传输SQL语句,避免被拦截和破解)

    减少网络流量(SQL保存在存储过程中,网络只要发送调用命令)

缺点:

    存储过程和开发程序分开,后期开发和维护以及调试比较麻烦

    不支持缓存

    不支持分布式

8、什么是feign

SpringCloud提供的声明式的REST客户端,实现远程的服务的调用,只需要编写接口和SpringMVC的注解就能完成调用。

实现步骤:

        在启动类上加@EnableFeignClients启动Feign的功能,就会启动对Feign接口的扫描

        扫描到@FeignClient注解接口,读取接口上的服务名、URL,包装后发给IOC容器

        由IOC容器通过动态代理机制创建RequestTemplate对象,发送Http请求,交给Http客户端处理

        Http客户端被封装到LoadBalanceClient负载均衡客户端中,交给Ribbon处理

十六 1、如何理解单点登录中的单点

单点登录SSO,分布式架构中通过一次登录,就能访问多个相关的服务。 

SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

2、int和Integer的区别

Integer是int的包装类;int是基本数据类型;Integer变量必须实例化后才能使用;int变量不需要;Integer实际是对象的引用,指向此new的Integer对象;int是直接存储数据值 ;Integer的默认值是null;int的默认值是0。 3、数据库的优化 6、访问修饰符Protected的作用

保护类型,能够被同一个包中的其它类和子类访问

7、Nginx的作用 8、主方法里的参数有什么用

字符串类型的数组

  在执行主方法的时候,可以传入一些参数,将来在主方法中,可以接收到这些参数

  Args是一个参数名称,任意修改

  String[]的中括号也可以写到args后面

9、static的作用

static 意思是静态,静态成员属于类,非静态的成员属于对象

作用:

    静态属性

    静态方法

    静态代码块

    静态内部类

静态属性和非静态属性的区别

    非静态属性属于对象,每个对象的属性都是独立副本

    静态属性属于类,内存分配在方法区,所有对象都共享这一个属性

静态的属性和方法可以通过类名和对象名调用,规范是使用类名调用

静态方法和非静态方法的区别:

    非静态方法必须通过对象调用,静态方法可以通过类名或对象调用

    非静态方法可以直接调用非静态的属性和方法以及静态的属性和方法

    静态方法只能直接调用静态的属性和方法

    非静态方法中可以使用this和super关键字,静态方法不可以

补充:静态方法可以被子类继承,通过子类名调用

静态代码块,定义在类中,属于类,随着类加载而调用,最先执行只执行一次,一般用于某些初始化的工作

十七 1、java的三大特征 2、JWT有几部分组成

头部:一个json字符串,包含当前令牌名称,以及加密算法,
载荷:一个json字符创,包含一些自定义的信息,
签名
由头部信息使用base64加密之后,拼接上载荷使用base64加密之后的部分,在加上当前的密钥,进行头部中的加密算法进行加密
这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。
将这三部分用.连接成一个完整的字符串,构成了最终的jwt

3、Kafka、ActiveMQ、RabbitMQ、RocketMQ有什么区别

 十八 1、hashmap和hashtable的区别 2、linkedlist和arraylist的区别 3、java的集合框架 4、数组、链表

为什么能在常数时间内访问数组元素? 

为了访问一个数组元素,该元素的内存地址需要计算其距离数组基地址的偏移量。需要用一个乘法计算偏移量,再加上基地址,就可以获得某个元素的内存地址。首先计算元素数据类型的存储大小,然后将它乘以元素在数组中的索引,最后加上基地址,就可以计算出该索引位置元素的地址了;整个过程可以看到需要一次乘法和一次加法就完成了,而这两个运算的执行时间都是常数时间,所以可以认为数组访问 *** 作能在常数时间内完成;

数组的优点

简单且易用;
访问元素快(常数时间);
数组的缺点

大小固定:数组的大小是静态的(在使用前必须制定数组的大小);
分配一个连续空间块:数组初始分配空间时,有时候无法分配能存储整个数组的内存空间(当数组规模太大时);
基于位置的插入 *** 作实现复杂:如果要在数组中的给定位置插入元素,那么可能就会需要移动存储在数组中的其他元素,这样才能腾出指定的位置来放插入的新元素;而如果在数组的开始位置插入元素,那么这样的移动 *** 作开销就会很大
链表是一种用于存储数据集合的数据结构,它是最简单的动态数据结构,我们在上面虽然实现了动态数组,但这仅仅是对于用户而言,其实底层还是维护的一个静态的数组,它之所以是动态的是因为我们在add和remove的时候进行了相应判断动态扩容或缩容而已,而链表则是真正意义上动态的数据结构;

链表的优点

真正的动态,不需要处理固定容量的问题;

能够在常数时间内扩展容量;

对比我们的数组,当创建数组时,我们必须分配能存储一定数量元素的内存,如果向数组中添加更多的元素,那么必须创建一个新的数组,然后把原数组中的元素复制到新数组中去,这将花费大量的时间;当然也可以通过给数组预先设定一个足够大的空间来防止上述时间的发生,但是这个方法可能会因为分配超过用户需要的空间而造成很大的内存浪费;而对于链表,初始时仅需要分配一个元素的存储空间,并且添加新的元素也很容易,不需要做任何内存复制和重新分配的 *** 作;

链表的缺点

丧失了随机访问的能力;

链表中的额外指针引用需要浪费内存;

链表有许多不足。链表的主要缺点在于访问单个元素的时间开销问题;数组是随时存取的,即存取数组中任一元素的时间开销为O(1),而链表在最差情况下访问一个元素的开销为O(n);数组在存取时间方面的另一个优点是内存的空间局部性,由于数组定义为连续的内存块,所以任何数组元素与其邻居是物理相邻的,这极大得益于现代CPU的缓存模式;

数组最好用于索引有语意的情况,最大的优点:支持快速查询;
链表不适用于索引有语意的情况,最大的优点:动态;

6、SpringCloud和SpringBoot的区别

1. spring boot使用了默认大于配置的理念,集成了快速开发的spring多个插件,同时自动过滤不需要配置的多余的插件,简化了项目的开发配置流程,一定程度上取消xml配置,是一套快速配置开发的脚手架,能快速开发单个微服务;

2. spring cloud大部分的功能插件都是基于springBoot去实现的,springCloud关注于全局的微服务整合和管理,将多个springBoot单体微服务进行整合以及管理;  springCloud依赖于springBoot开发,而springBoot可以独立开发;

7、SpringCloud的组件及作用 8、Eureka是如何发现服务的(原理)

1.提供者将IP和端口注册到注册中心
2.注册中心和提供者每隔一段时间(60s)发送心跳包
3.如果一段时间(90s)没有收到心跳,注册中心就会将服务剔除
4.消费者需要调用提供者时,会到注册中心上查找,注册中提供服务清单
5.消费者通过服务清单中的IP和端口来调用提供者
6.服务清单每隔一段时间(30s)更新一次

9、负载均衡是什么,它的作用

因为请求量特别大的情况下,必须有多台服务来进行处理,配置集群。集群中的机器可能出现忙闲不均的情况,就需要有一套机制,实现平均分配请求量到每台机器上

负载均衡的作用:

1.解决并发压力,提高应用处理性能

2.提供故障转移,实现高可用

3.通过添加或减少服务器数量,提供网站伸缩性

4.安全防护

10、Nginx 11、断路器的作用,讲讲雪崩效应

当一个服务调用另一个服务由于网络原因或者自身原因出现问题时 调用者就会等待被调用者的响应 当更多的服务请求到这些资源时导致更多的请求等待 这样就会发生连锁效应(雪崩效应) 断路器就是解决这一问题。

服务的雪崩:

服务的调用是链式的,一个服务出现长时间阻塞,就会阻塞后面调用它的服务,导致整个服务链都不可用

熔断:

被调用的服务一直没有响应,直接断开连接

降级:

服务熔断后,服务由正常降级为缺省,返回兜底数据(缺省数据)

12、说一下关系型数据库MySQL和非关系型数据库Redis的区别,及应用场景

关系型数据库存储结构是二维表结构,类似依据x,y可以定位一个数据;

基于行式存储,存储结构化数据,一行代表一条完整的信息。

关系型数据库遵循ACID特性(原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)),支持事务处理能力。

但容量扩展性有限。

数据库的ACID & 3种隔离级别 脏读、不可重复读、幻读

适用场景:

需要事务支持;

基于sql的结构化查询存储,处理复杂的关系。

缓存型数据库
(1)Redis
key -> value(String、list、set、hash(field-value)、zset(score-value))

内存中数据有时间限制,也提供RDB和AOF两种持久化方式。

(2)Memcached
区别是不会持久化,完全基于内存,基本被Redis替代了。

适用场景:

对数据高并发的读写(mysql数据库存储在磁盘上,高并发会产生大量IO)

对海量数据的读写(mysql数据库不支持海量数据)

对数据高可扩展性的(例如key-value,redis中支持5种类型的value)

13、内连接和左连接的区别

使用内连接时,不符合连接条件的数据,(不管是左表中的还是右表中的)都不会被组织到结果集中

使用左外连接时,对于不符合连接条件的数据,左表中的内容依然会被组织到结果集中,结果集中该条数据对应的右表部分为 null

十九 5、分布式锁怎么实现

选用Redis实现分布式锁原因:

(1)Redis有很高的性能;
(2)Redis命令对此支持较好,实现起来比较方便

在使用Redis实现分布式锁的时候,主要就会使用到这三个命令。

(1)获取锁的时候,使用setnx加锁,并使用expire命令为锁添加一个超时时间,超过该时间则自动释放锁,锁的value值为一个随机生成的UUID,通过此在释放锁的时候进行判断。

(2)获取锁的时候还设置一个获取的超时时间,若超过这个时间则放弃获取锁。

(3)释放锁的时候,通过UUID判断是不是该锁,若是该锁,则执行delete进行锁释放。

6、类与对象

类是对象的一种抽象,可以看做是具有相同特性和行为的对象的总和

如:人类

对象是具体存在的实例

如:具体的某一个人

7、集合 8、hashset

数据结构:散列表

通过哈希算法(散列)计算数据的位置,无序

注意:添加的数据必须实现hashCode和equals方法

HashSet中封装一个HashMap集合,数据添加到HashMap的键

9、线程的生命周期

线程几种状态:

新建 NEW

准备/就绪 START

运行 RUNNING

阻塞 BLOCKING

死亡 DEAD

10、sleep和wait的区别 二十 1、java集合 2、数据库中的存储过程 3、数据库左连接和右连接

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5716306.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存