百度测开面试复习

一、测开实习部分

1、实习期间主要做了哪些工作

  • 熟悉测试流程:理解需求文档,参与需求 KT(Knowledge Transfer),测试用例编写,测试用例执行(包括回归测试),编写测试报告
  • 独立完成测试工具后端接口开发
  • 独立承接测试需求,实现关键链路自动化测试

2、实习做的项目用了哪些技术栈

Spring、Spring MVC、Spring Boot、MybatisPlus、PostMan、Swagger、DevCube

3、实习测试主要负责哪些方面的测试,接口测试是怎么测试的,针对http接口自动化测试如何进行的

业务功能测试和接口自动化测试。

本地用PostMan进行接口自动测试(详细步骤见12),再用众安企业内部的接口测试工具DevCube进行二次验证,最后才能上生产。

4、说一下工作中是如何进行测试工作的

  • 理解需求文档,参与需求 KT(Knowledge Transfer);
  • 测试用例编写,然后与BA和开发进行三方的测试用例评审;
  • 测试用例执行(包括回归测试和冒烟测试):先在测试环境进行测试,测试环境通过将代码发到预发环境进行测试,预发环境通过,接着请业务老师进行业务验收;
  • 验收通过将代码发到生产环境,最后编写测试报告;

5、在需求评审中需要干些什么(需求KT)

  • 确认将要实现的内容,以及要达到什么样的目的;
  • 确认方案的可行性,查漏补缺;
  • 了解自己所负责的内容,并提出自己的疑问然后解决疑惑;
  • 确认交付内容的时间目标,目标达成一致;

6、印象深刻的bug,最后是怎么解决的

我的第一个测试任务上线,当时几乎临近ddl,突然发现自己的测试的功能覆盖率没通过。当时心急如焚,但是在mentor的耐心指导下,她教我如何看DevCube的代码日志,定位代码中没有覆盖到的地方,一点点的把功能覆盖率提升上来,最终让产品按时上线了。

7、工作中是如何跟进bug的

在DevCube上提出缺陷,然后开发收到消息后,进行bug修复,修复完成让我进行测试,测试通过,再在DevCube上点测试通过,才一个bug完全修复。但是也会有没有修复的bug,每周会有组会把这些没有修复的bug拉出来对齐是哪个人负责的,不能解决的开发一起想办法把它解决了。

8、提的bug开发不认怎么办?过程怎么保证测试质量?你都是怎么定位bug的,举个例子?

每一个测试项目我们都会为其编写测试对应的计划的,在执行测试用例的过程中,我们会保留测试数据作为证据,并将对应的bug提到DevCube上。

9、怎么定位404和502的缺陷来源?

状态码404资源不存在,502网关有问题。然后客户端错误就看一下请求url之类的,服务端错误就检查服务器运行cpu和进程,排查错误日志。

  • HTTP 错误 400: 400 请求出错  由于语法格式有误,服务器无法理解此请求。不作修改,客户程序就无法重复此请求。 
  • HTTP 错误 405:405 不允许此方法   对于请求所标识的资源,不允许使用请求行中所指定的方法。请确保为所请求的资源设置了正确的 MIME 类型。
  • HTTP 错误 406:406 不可接受 根据此请求中所发送的“接受”标题,此请求所标识的资源只能生成内容特征为“不可接受”的响应实体。
  • HTTP 错误 407:407 需要代理身份验证   在可为此请求提供服务之前,您必须验证此代理服务器。请登录到代理服务器,然后重试。 
  • HTTP 错误 412:412 前提条件失败   在服务器上测试前提条件时,部分请求标题字段中所给定的前提条件估计为FALSE。客户机将前提条件放置在当前资源 metainformation(标题字段数据)中,以防止所请求的方法被误用到其他资源。
  • HTTP 错误 414:414 Request-URI 太长   Request-URL太长,服务器拒绝服务此请求。仅在下列条件下才有可能发生此条件:  客户机错误地将 POST 请求转换为具有较长的查询信息的 GET 请求。  客户机遇到了重定向问题(例如,指向自身的后缀的重定向前缀)。   服务器正遭受试图利用某些服务器(将固定长度的缓冲区用于读取或执行 Request-URI)中的安全性漏洞的客户干扰。
  • HTTP 错误 500:500 服务器的内部错误   Web 服务器不能执行此请求。请稍后重试此请求。
  • HTTP 错误 501:501 未实现   Web 服务器不支持实现此请求所需的功能。请检查URL 中的错误
  • HTTP 错误 502:502 网关出错   当用作网关或代理时,服务器将从试图实现此请求时所访问的upstream 服务器中接收无效的响应。

10. http和https的区别

  • https就是http+SSL加密,https更安全;
  • http端口80,https443;
  • https的SSL用的PKI需要CA颁发的证书,需要费用;
  • http是简单无状态的,而https是需要身份验证、消息完整性验证还有加密传输的。

11、HTTP协议(主要是GET,POST,PUT,DELETE)

客户端用到的手段,只能是HTTP协议。具体来说,就是HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。
它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。比如,文本可以用txt格式表现,也可以用HTML格式、XML格式、JSON格式表现,甚至可以采用二进制格式;图片可以用JPG格式表现,也可以用PNG格式表现。

  • GET (SELECT):从服务器检索特定资源,或资源列表。
  • POST (CREATE):在服务器上创建一个新的资源。
  • PUT (UPDATE):更新服务器上的资源,提供整个资源。
  • PATCH (UPDATE):更新服务器上的资源,仅提供更改的属性。
  • DELETE (DELETE):从服务器删除资源。

12、用过什么自动化测试框架(PostMan、Swager) 

(1)为什么要做接口测试?好处是什么

  •    接口测试是测试系统组件间接口的一种测试。
  •    接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。
  •    测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等。

好处:

  • 节约时间,缩短项目时间
  • 提高工作效率
  • 提高系统的健壮性
  • 很多系统关联都是基于接口来实现,接口测试可以将复杂的系统关联进行简化。
  • 接口功能比较单一,能够比较好的进行测试覆盖,也相对容易实现自动化持续集成。
  • 接口相对于界面功能,会更底层一些,测试覆盖会更容易。

(2) 如何使用PostMan进行接口测试

13、常见的测试方式有哪些

单元测试、集成测试、冒烟测试、系统测试、回归测试、验收测试

  • 单元测试:最小设计单元(模块)的验证,确保模块被正确编码,对重要控制路径进行测试以发现模块内错误,通常情况下是白盒测试,对代码风格和规则、程序设计和结构、业务逻辑等进行静态测试,及早发现解决不易显现的错误。
  • 集成测试:通过测试发现与模块接口有关的问题,将通过了单元测试的模块拿来,构造一个在设计中所描述的程序结构,避免一次性的继承,采用增量继承。测试接口是否一致、模块间数据流控制流是否按照设计实现其功能、以及结果的正确性验证。可以是整个产品的集成测试,也可以是大模块的集成测试。(黑盒白盒相结合)
  1. 自顶向下集成:首先集成主模块,按控制层次结构向下集成,隶属于主模块的模块按照深度优先或广度优先的方式集成到整个结构中去。
  2. 自底向上集成:从原子模块开始构造和测试,因为模块是自底向上集成的,进行时要求所有隶属于某个给顶层次的模块总是存在的,也不再有使用稳定测试桩的必要。
  • 冒烟测试:针对每个版本或每次需求变更后,在正式测试前,对产品或系统的一次简单的验证性测试。用于确认代码中的更改会按预期运行,且不会破坏整个版本的稳定性。
  • 系统测试:基于系统整体性需求说明书的黑盒类测试,覆盖系统所有联合部件。系统测试是针对整个产品系统进行的测试,目的是验证系统是否满足需求规格的定义,找出不符或与之矛盾的地方。系统测试的对象:需要测试的的系统产品的软件、软件依赖的硬件、外设甚至某些数据、某些支持软件和接口等。因此,将以上所有结合起来,在系统实际运行环境中测试。
  • 回归测试:回归测试是指修改了旧代码后,重复以前的全部或部分的相同测试以确认修改没有引入新的错误或导致其他代码产生错误
  • 验收测试:系统开发生命周期方法论的一个阶段,这时相关用户和独立测试人员根据测试计划和结果对系统进行测试和验收,它让系统用户决定是否接收系统,它是一项是否能够满足合同或用户所规定需求的测试,包括(测试环境测试,预发环境测试,生产环境测试)
  1. 测试环境测试:内测版本,开发者内部交流;是由用户在开发者的场所来进行的,在一个受控的环境中进行。测试完后一般不会有大问题
  2. 预发环境测试:公测版本,面向所有用户;由软件的最终用户在一个或多个用户场所来进行的,开发者通常不在现场,用户记录测试中遇到的问题并报告给开发者,开发者对系统进行最后的修改,并开始准备发布最终的软件。
  3. 生产环境测试:指软件正式发行的候选版,相当成熟,与正式版本相差无几,成为正式发布的候选版。

二、Java八股部分

1、mysql数据量大怎么办,怎么优化

(1)单表优化

a.单表优化

  • MySQL在5.1之后才有的,可以看做是水平拆分,分区表需要在建表的需要加上分区参数,用户需要在建表的时候加上分区参数;
  • 分区表底层由多个物理子表组成,但是对于代码来说,分区表是透明的;
  • SQL中的条件中最好能带上分区条件的列,这样可以定位到少量的分区上,否则就会扫描全部分区。

b.增加缓存

  • 主要的思想就是减少对数据库的访问,缓存可以在整个架构中的很多地方;
  • 比如:数据库本身有就缓存,客户端缓存,数据库访问层对SQL语句的缓存,应用程序内的缓存,第三方缓存(如Redis等)

c.字段设计

  • 单表不要有太多字段;
  • VARCHAR的长度尽量只分配真正需要的空间;
  • 尽量使用TIMESTAMP而非DATETIME;
  • 避免使用NULL,可以通过设置默认值解决。

d.索引优化

  • 索引不是越多越好,针对性地建立索引,索引会加速查询,但是对新增、修改、删除会造成一定的影响;
  • 值域很少的字段不适合建索引;
  • 尽量不用UNIQUE,不要设置外键,由程序保证;
  • 避免前导模糊查询,避免隐式转换,避免等号左边做函数运算,in中的元素不宜过多等等

e.使用非关系型数据库NoSQL

  • 统计类、日志类、弱结构化的数据;事务要求低的场景

(2)表拆分

a.垂直拆分

垂直拆分的意思就是把一个字段较多的表,拆分成多个字段较少的表;上文中也说过单表的字段不宜过多,如果初期的表结构设计的就很好,就不会有垂直拆分的问题了;一般来说,MySQL单表的字段最好不要超过二三十个。

b.水平拆分

就是我们常说的分库分表了;分表,解决了单表数据过大的问题,但是毕竟还在同一台数据库服务器上,所以IO、CPU、网络方面的压力,并不会得到彻底的缓解,这个可以通过分库来解决。

水平拆分优点很明显,可以利用多台数据库服务器的资源,提高了系统的负载能力;缺点是逻辑会变得复杂,跨节点的数据关联性能差,维护难度大(特别是扩容的时候)

2、索引结构,建索引的坏处

  • 创建索引和维护索引需要时间成本,这个成本随着数据量的增加而加大。
  • 创建索引和维护索引需要空间成本,每一条索引都要占据数据库的物理存储空间,数据量越大,占用及空间也越大(数据表占据的是数据库的数据空间)
  • 会降低表的增删改的效率,因为每次增删改索引需要进行动态维护,导致时间边长。

3、数据库有峰值请求怎么办

  • 很直观的指标,你的数据库访问次数过多了,可以通过缓存减少查询次数、 消息队列 削峰
  • 削峰,也就是消除峰值的最大QPS,有几种削峰策略:

       a.设置两次请求最小有效时间间隔:设置两次请求最小有效时间间隔,假设最小时间间隔是t,那么在小于t的时间的请求都视为无效请求,忽略掉。像红包雨这类频繁请求的活动,该策略非常有效。

       b.概率请求策略:如果不想每次都让用户去请求,给用户请求的动作加一个概率P,那么每次发送请求的概率就是P,这个时候需要结合a的策略去控制用户的每秒请求次数。

      c.公平性策略:这里提供一种公平性策略的方式,随机算法+插值算法,生成有效请求序列。

5、redis,mysql 和 mongodb 的区别 

MySQL、MongoDB、Redis 数据库之间的区别 - 简书 (jianshu.com)

6、Spring boot的默认端口号是什么?怎么换成其他的端口号?

  • Springboot启动的时候,端口的设定默认是8080;
  • Springboot提供了两种方式,第一种,我们可以通过application.yml配置文件配置,
  • 第二种,可以通过代码里面指定,在开发中,建议使用修改application.yml的方式来修改端口。

application.yml:

server:
  #端口号
  port: 8888
  #项目名,如果不设定,默认是 /
  context-path: /demo

application.properties:

server.port=8081
server.context-path=/demo

7、TCP和UDP的区别

  • TCP是面向连接的,UDP是无连接的

  • TCP是可靠的,UDP是不可靠的

  • TCP是面向字节流的,UDP是面向数据报文的

  • TCP只支持点对点通信,UDP支持一对一,一对多,多对多

  • TCP报文首部20个字节,UDP首部8个字节

  • TCP有拥塞控制机制,UDP没有

  • TCP协议下双方发送接受缓冲区都有,UDP并无实际意义上的发送缓冲区,但是存在接受缓冲区

8、线程和进程的区别

  • 地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间
  • 资源拥有:同一进程内的线程共享本进程的资源,但是进程之间的资源是独立的。
  • 一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。
  • 进程切换时,消耗的资源大,效率高。所以涉及到频繁的切换时,使用线程要好于进程。同样如果要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程。
  • 执行过程:每个独立的进程程有一个程序运行的入口、顺序执行序列和程序入口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
  • 线程是处理器调度的基本单位,但是进程不是。
  • 两者均可并发执行。

9、判断IP地址的合法性

IPv4的ip地址格式:(1~255).(0~255).(0~255).(0~255)

正则表达式判定法:

最简单的实现方法是构造一个正则表达式。判断用户的输入与正则表达式是否匹配。若匹配则是正确的IP地址,否则不是正确的IP地址。

下面给出相对应的验证ip的正则表达式:

^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])\.
(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.
(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.
(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$

-------------------------------------
\d表示0~9的任何一个数字

{2}表示正好出现两次

[0-4]表示0~4的任何一个数字

| 的意思是或者

1\d{2}的意思就是100~199之间的任意一个数字

2[0-4]\d的意思是200~249之间的任意一个数字

25[0-5]的意思是250~255之间的任意一个数字

[1-9]\d的意思是10~99之间的任意一个数字

[1-9])的意思是1~9之间的任意一个数字

\.的意思是.点要转义(特殊字符类似,@都要加\\转义)

11、日志文件你知道吗?

在Java程序中常用日志框架可以分为两类:

  • 无具体实现的抽象门面框架,如:Commons Logging、SLF4J
  • 具体实现的框架,如:Log4j,Log4j2,Logback,Jul


12、一次性在请求中发送了20条SQL语句,你怎么判断哪条语句出现了错误?

通过事务控制多条sql同时执行,如果成功就把数据全部写入硬盘,否则全部回滚。

13、浏览器输入url之后到页面出现这中间发生了什么

在浏览器输入 URL 回车之后发生了什么(超详细版) - 知乎 (zhihu.com)

  • 用户在浏览器地址栏输入URL “ https://www.baidu.com/ ”。
  • 浏览器查找当前URL的DNS缓存记录。
  • DNS解析URL对应的IP。
  • 根据IP建立TCP连接(三次握手)。
  • HTTP发起请求。
  • 服务器处理请求并返回HTTP报文。
  • 浏览器解析渲染页面

14、场景:海量数据查询如何优化?

  • 缓存加速:缓存就是为了弥补存储系统在这些复杂业务场景下的不足,其基本原理是将可能重复使用的数据放到内存中,一次生成、多次使用,避免每次使用都去访问存储系统。
  • 读写分离:每次写数据时会同步多份到其它的存储系统,生成多个备份,当用户读取数据时直接从备份存储系统获取数据。应用场景为读多写少
  • 垂直拆分:垂直拆分是指按照业务功能拆分,业务表分布在不同的数据库上,这样也就将数据或者说压力分担到不同的库上面 。比如电商系统会拆分出会员、商品、交易、类目、营销、搜索等业务库,分别归属到不用的技术团队维护。
  • 分库分表:数据库垂直拆分后,遇到单机数据库性能瓶颈,我们可以考虑分表。分表又可以细分为 垂直分表水平分表 两种形式。数据表垂直拆分就是纵向地把一张表中的列拆分到多个表,表由“宽”变“窄”,简单来讲,就是将大表拆成多张小表。水平分表:表结构维持不变,对数据行进行切分,将表中的某些行切分到一张表中,而另外的某些行又切分到其他的表中,也就是说拆分后数据集的并集等于拆分前的数据集。
  • 冷热数据分离:从数据的使用频率来看,经常被业务访问的数据称为热点数据;反之,称之为冷数据。
  • NoSQL:NoSQL 数据库放弃了与分布式环境相悖的 ACID 事务,提供了另一种聚合数据模型,从而具有可伸缩性的非关系数据库。

15、多个表如何保证数据一致性?

通过预写式日志,undo log保证原子性,redo log保证持久性,设置隔离级别,保证并发事务进行的时候,保证数据一致性。

如果整个事务执行的过程系统崩溃或者断电了,在系统重启的时候,恢复机制会将redo log中已提交的事务重做,保证事务的持久性;而undo log中未提交的事务进行回滚,保证事务的原子性。

Mysql通过预写式日志,保证了原子性和持久性。那么在多个事务并行的情况下,是否还能保证数据的一致性?如果A事务能够访问B事务正在提交的数据,然后B事务又做出了回滚,这样是不是就让数据乱套了。所以事务并行的情况下,这样是不够的。

隔离性:引入锁机制来保证。那么是什么情况下不锁,什么情况下锁呢?还有读写分离需要实现吗?这就需要去说说四种级别的隔离性

  • 未提交读:A事务可以读取B事务正在修改的数据,但是会出现B事务如果回滚,这样数据前后不一致,会造成脏读的现象。
  • 已提交读:A事务只能读取B事务已提交的数据。B事务修改数据,A事务进行读取,数据未改,当B事务提交数据后,A事务读取数据不一致。这是幻读现象,因为同一个事务,我读取两次相同的数据返回的是不同的,这样并未保证一致性。
  • 可重复读:利用MVCC并发版本控制,B事务修改数据,A事务进行读取,数据未改,当B事务提交后,A事务读取数据,这个时候会返回A数据之前读的版本。
  • 序列化:简单粗暴,读锁和写锁都是排它锁,不管读操作还是写操作都是会对数据上锁。这样粗暴造成性能下降很多。
     

16、介绍一下事务,有哪些特点,什么场景需要用到事务

事务ACID特性:

  • 原子性(Atomicity) : 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
  • 一致性(Consistency): 执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的;
  • 隔离性(Isolation): 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
  • 持久性(Durability): 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

事务适用条件:

事务的提出主要是为了解决并发情况下保持数据一致性的问题(类似于多线程)
事务(Transaction)是并发控制的基本单位。所谓的事务,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。例如,银行转账工作:从一个账号扣款并使另一个账号增款,这两个操作要么都执行,要么都不执行,在关系数据库中,一个事务可以是一条SQL语句、一组SQL语句或整个程序。 。所以,应该把它们看成一个事务。事务是数据库维护数据一致性的单位,在每个事务结束时,都能保持数据一致性。

17、Spring boot修改了代码之后如何不重启服务也能生效?

SpringBoot实现热部署,修改代码不用重启服务:在pom文件中添加spring-boot-devtools热部署依赖

<dependency>
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-devtools</artifactId>
</dependency> 

18、说一说JVM虚拟机,垃圾回收机制

JVM的垃圾回收机制是指在JVM中,有一个垃圾回收线程,它是低优先级的,在正常情况下是不会执行的,只有在虚拟机空闲或者当前堆内存不足时,才会触发执行。垃圾回收的过程主要包括以下几个步骤:

  • 判定垃圾回收的对象。回收垃圾之前,首先要找到需要被当作垃圾而回收的对象。JVM分为五个区域——程序计数器、虚拟机栈、本地方法栈、堆、方法区。我们知道程序计数器与栈均是线程私有的,其生命周期取决于线程的生命周期。
  • 标记存活对象。可达性算法是为了标记存活的对象,知道哪些是可回收对象。
  • 垃圾回收算法进行回收。常见的几种垃圾回收算法标记清除、复制算法、标记整理和分代收集算法。
  • 压缩内存空间。在进行完垃圾回收之后,可能会出现内存空间不连续的情况,需要进行内存压缩。

19、Spring了解吗,AOP底层原理是什么

AOP 面向切面编程,其 底层 原理就是动态代理 实现 。 如果切面策略目标有接口 实现 ,使用 JDK 的动态代理技术;无接口 实现 则使用CGLIB技术生成动态代理。

21、Java创建多线程有哪些方式

(1)继承Thread类创建线程

  • 定义Tread类的子类MyThread,并重写run()方法.run()方法的方法体(线程执行体)就是线程要执行的任务。
  • 创建MyThread类的实例
  • 调用子类实例的start()方法来启动线程

(2)实现Runnable接口创建线程

  • 定义Runnable接口的实现类,必须重写run()方法,这个run()方法和Thread中的run()方法一样,是线程的执行体
  • 创建Runnable实现类的实例,并用这个实例作为Thread的target来创建Thread对象,这个Thread对象才是真正的线程对象
  • 调用start()方法

(3) 使用Callable和Future创建线程

  • 创建Callable接口的实现类,并实现call()方法,然后创建该实现类的实例(从java8开始可以直接使用Lambda表达式创建Callable对象)。
  • 使用FutureTask类来包装Callable对象,该FutureTask对象封装了Callable对象的call()方法的返回值
  • 使用FutureTask对象作为Thread对象的target创建并启动线程(因为FutureTask实现了Runnable接口)
  • 调用FutureTask对象的get()方法来获得子线程执行结束后的返回值

(4)使用线程池创建(使用java.util.concurrent.Executor接口)

创建一个可缓存的线程池,调用execute将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线   程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。

22、说一下ArryList和LinkedList特点,有什么区别,为什么它们有这样的特点


23、说一下java的浅拷贝和深拷贝

 (1) 浅拷贝:
      浅拷贝又称为浅复制,浅克隆,浅拷贝是指拷贝时只拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用所指向的对象,拷贝出来的对象的所有变量的值都含有与原来对象相同的值,而所有对其他对象的引用都指向原来的对象,简单地说,浅拷贝只拷贝对象不拷贝引用。
(2) 深拷贝:
      深拷贝又称为深复制,深克隆,深拷贝不仅拷贝对象本身,而且还拷贝对象包含的引用所指向的对象,拷贝出来的对象的所有变量(不包含那些引用其他对象的变量)的值都含有与原来对象的相同的值,那些引用其他对象的变量将指向新复制出来的新对象,而不指向原来的对象,简单地说,深拷贝不仅拷贝对象,而且还拷贝对象包含的引用所指向的对象。

再简单的说就是浅拷贝只拷贝对象,不拷贝引用。深拷贝对象引用全拷贝
(3) Java中常用的拷贝操作有三种:a.操作符= ;b.拷贝构造函数; c. clone( )方法。由于Java不支持运算符重载,所以我们不能在自己定义的类中定级操作符=操作。拷贝构造函数就不多说了,我们经常遇到。主要说一下clone方法,如果我们想要使自己定义的对象能够实现深拷贝,就需要改写从Object类中继承来的clone方法,clone方法在Object类中是protected权限,是为了防止意外的支持clone操作,所以我们需要把它改写成public权限的

24、数据库中有20000条数据,如何查询得到前80%范围的数据

select top 20000*0.8 from table_name

25、了解Redis吗,数据结构有哪些,使用Redis有什么好处

(1)数据结构

  • Redis的5种常见数据结构:字符串(String)、列表(List)、散列(Hash)、集合(Set)、有序集合(Sorted Set),这些都是Redis对外暴露的数据结构。
  • Redis底层数据结构有六种:简单动态字符串(SDS)、列表、字典、整数集合、跳跃表、压缩列表、快速列表。

(2)使用Redis有什么好处

  • 纯内存操作
  • 响应快速

  • 单线程操作,避免了频繁的上下文切换。
  • 采用了非阻塞I/O多路复用机制。
  • 丰富的数据类型

27、TCP3次握手过程,为什么TCP需要3次握手,4次挥手。

(1)三次握手的步骤如下:

  • 客户端向服务器发送一个SYN包,表示请求建立连接。
  • 服务器接收到客户端发来的SYN包后,对该包进行确认后结束LISTEN阶段,并返回一段TCP报文,表示确认客户端的报文序号有效,服务器能正常接收客户端发送的数据,并同意创建新连接。
  • 客户端接收到服务器发来的TCP报文后,再向服务器发送一段确认报文,表示客户端已经准备好发送数据。

(2)四次挥手的步骤如下:

  • 客户端向服务器发送一个FIN包,表示请求断开连接。
  • 服务器接收到客户端发来的FIN包后,对该包进行确认后进入CLOSE_WAIT状态。
  • 服务器向客户端发送一个ACK包,表示已经准备好断开连接。
  • 客户端接收到服务器发来的ACK包后,进入TIME_WAIT状态,并向服务器发送一个FIN包,表示已经准备好断开连接。

由TCP的三次握手和四次断开可以看出,TCP使用面向连接的通信方式, 大大提高了数据通信的可靠性,使发送数据端和接收端在数据正式传输前就有了交互, 为数据正式传输打下了可靠的基础。

28、除了基本的排序算法还了解哪些算法,堆排序原理介绍一下,用在哪些场景

冒泡排序直接插入排序希尔排序选择排序快速排序归并排序、堆排序

29、双亲委派机制

某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,子加载器才会尝试自己去加载。

  • 如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行;
  • 如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器;
  • 如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式。

30、线程的几种状态,最常见的几种状态

线程的生命周期主要有以下六种状态:

  • New(新创建)
  • Runnable(可运行)
  • Blocked(被阻塞)
  • Waiting(等待)
  • Timed Waiting(计时等待)
  • Terminated(被终止)

31、Group by和Order by的区别

  • order by 从英文里理解就是行的排序方式,默认的为升序。 order by 后面必须列出排序的字段名,可以是多个字段名。
  • group by 从英文里理解就是分组。必须有“聚合函数”来配合才能使用,使用时至少需要一个分组标志字段。
  • 在使用group by的语句中,只能select用于分类的列(表达式),或聚合函数。where条件用于group by之前,having用于group by 之后对结果进行筛选。
  • 注意:聚合函数是---sum()、count()、avg()等都是“聚合函数

三、算法题部分

  1. 写道题吧 三数之和 

  2. 对数组进行排序,奇数放前面,偶数放后面(两个算法都很简单)

  3. 手撕:diff json串

  4. 找倒数第k个节点,找数组最大和

  5.  输出1-100的质数

  6. 数据库输出前五名的学生信息(表中只有成绩和学生姓名)


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

金州饿霸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值