初学java第一行写什么以下代码每行是什么意思可以给我解释以下吗?

1、下面对方法的作用描述不正确的是:( d d )
A、 使程序结构清晰 B、 功能复用 C、 代码简洁 D、 重复代码
2、方法内定义的变量:( b b )
A 、一定在方法内所有位置可见 B、 可能在方法内的局部位置可见
C、 在方法外可以使用 D、 在方法外可见
3、方法的形参:( a)
A、可以没有 B、至少有一个 C、必须定义多个形参 D、只能是简单变量
4、方法的调用:( c)
A、必须是一条完整的语句 B、只能是一个表达式
C、可能是语句,也可能是表达式 D、必须提供实际参数
A、不能用来返回对象 B、只可以返回数值
C、方法都必须含有 D、一个方法中可以有多个 return 语句
A、方法体为空 B、方法体没有意义
C、定义方法时必须使用 D、方法没有返回值
8、方法重载所涉及的方法:( a )
A、有相同的名字 B、参数个数必须不同 C、参数类型必须不同 D、返回类型必须不同
9、下面关于类和对象之间关系的描述,正确的是( c c )
A、联接关系 B、包含关系 C、具体与抽象的关系 D、类是对象的具体化
10、下面关于java中类的说法哪个是不正确的( c )
A、类体中只能有变量定义和成员方法的定义,不能有其他语句。
B、构造方法是类中的特殊方法。
C、类一定要声明为public的,才可以执行。
D、一个java文件中可以有多个class定义。
11、下列哪个类声明是正确的( d)
12、下面的方法声明中,哪个是正确的( c c)
13、下述哪些说法是不正确的?( b )
A、 实例变量是类的成员变量 B、 实例变量是用static关键字声明的
C、 方法变量在方法执行时创建 D、方法变量在使用之前必须初始化
14、下面对构造方法的描述不正确是( b b )。
A、 系统提供默认的构造方法 B、 构造方法可以有参数,所以也可以有返回值
C、 构造方法可以重载 D、 构造方法可以设置参数

主要介绍了Java编程常见内存溢出异常与代码示例,具有一定参考价值,需要的朋友可以了解下。

如何基于 JVM 分析内存使用对象?

上一讲我带你学习了基于 JVM 的线程分析,相信你已经可以通过热点线程分析出哪些方法在消耗 CPU,拿到这些方法之后你就可以和研发人员讨论后续的优化方案了。那这一讲我们就来重点学习 JVM 内存是如何管理的,有哪些手段可以分析内存对象,并帮助你定位内存的瓶颈。

提到分析 JVM 的内存对象,可能你会问我,之前讲过如何判断服务器内存瓶颈,那 JVM 内存和服务器内存有什么联系呢。我们先来看下这两者的关系,如下图所示:

图 1:内存关系示意图

其实二者的关系很简单,对于服务器系统而言,JVM 只是其中的一部分。当操作系统内存出现瓶颈时,我们便会重点排查哪些应用会占用内存。不过对于更深一步分析内存的使用,并不仅仅是统计使用、空闲等这些数值,我们需要进一步去了解内存结构,以及内存如何分配、如何回收,这样你才能更好地确定内存的问题。

通过第 14 讲的学习你可以知道,Java 文件一般是先编译成 class 结尾的文件,然后通过类加载器到 JVM 内存中。接着我们来看看 JVM 内存结构图,这样能够对它有个全局的了解。

图 2:JVM 内存分配示意图

f 中添加,这样的方式需要重启 MySQL 服务。

(2)如何获取慢 SQL?

你在分析慢 SQL 之前首先需要获取慢 SQL,如何获取慢 SQL 呢,其中的一种方式是在 my.cnf 中配置,如下示意:

你就可以将慢 SQL 写入相应的日志文件内。除了这个方法,在测试过程中,我也会使用 show full processlist 这个命令实时获取交互的 SQL,通过观察 state 状态以及 SQL 出现的频率也能判断出来是不是慢 SQL。

(3)如何分析慢 SQL?

关于慢 SQL,绝大多数原因都是 SQL 本身的问题,比如写的业务 SQL 不合理,返回了大量数据;表设计不合理需要多表的连接查询;索引的问题等。在我的经验当中,众多 SQL 问题中索引相关的问题也是最突出的,在我看来索引的相关问题有以下几种。

首先来看看什么是索引,索引是一种单独地、物理地对数据库表中一列或者多列进行排序的数据库结构。索引的作用相当于图书的目录,可以根据目录的页码快速找到所需要的内容。当数据库存在大量数据做查询操作,你就需要 check 是否存在索引,如果没有索引,会非常影响查询速度。

在 InnoDB 中,我们可以简单地把索引分成两种:聚簇索引(主键)和普通索引。按照我的理解来看,聚簇索引是叶子节点保存了数据,而普通索引的叶子节点保存的是数据地址。

通常推荐在区分度较高的字段上创建索引,这样效果比较好,比如,一个会员系统中,给用户名建索引,查询时候可以快速定位到要找的数据,而给性别字段建索引则没有意义。

添加索引只是其中的一个必要步骤,并不是添加完成后就万事大吉了。在一些情况下索引其实是不生效的,比如索引列中存在 Null 值、重复数据较多的列、前导模糊查询不能利用索引(like '%XX' 或者 like '%XX%')等。在一般情况下你可以使用执行计划查看索引是否真正生效,在下一讲中,我也会用更多的实例带你看这个问题。

联合索引不满足最左前缀原则

又来新概念了,有两个问题:

首先来解释下联合索引,用大白话解释就是一个索引会同时对应多个列,比如 c1、c2、c3 为三个字段,则可以通过 index_name(c1,c2,c3) 的方式建立联合索引,这样做的好处是什么呢?通过这样的方式建立索引,等于为 c1、(c1,c2)、(c1,c2,c3) 都建立了索引。因为每增加一个索引,也会增加写操作的磁盘开销,所以说联合索引是一种性价比比较高的建立索引的方式。

那么什么是最左前缀原则呢?你刚刚在 c1、c2、c3 上建立了联合索引,索引中的数据也是按 c1、c2、c3 进行排序,最左前缀顾名思义就是最左边的优先,比如如下 SQL 命令:

这条 SQL 就会按照从左到右的匹配规则,如果打破最左前缀规则联合索引是不生效的,如下写法所示:

那如何判断 SQL 有没有走索引或者索引有没有生效呢?接下来我们要了解一个新概念叫作执行计划,什么是执行计划呢?

执行计划通常是开发者拿到慢 SQL 之后,优化 SQL 语句的第一步。MySQL 在解析 SQL 语句时,会生成多套执行方案,然后内部会进行一个成本的计算,通过优化器选择一个最优的方案执行,然后根据这个方案会生成一个执行计划。开发者通过查看 SQL 语句的执行计划,可以直观地了解到 MySQL 是如何解析执行这条 SQL 语句的,然后再针对性地进行优化。

(4)如何查看 SQL 语句的执行计划?

我们可以在执行 SQL 的前面添加 desc,如下所示:

对于 explain 返回的内容我选择一些重点解释一下,尤其是对性能产生不利的表现内容

table 显示的是这一行的数据是关于哪张表的,上述内容中显示的表名就是 user。

这是重要的列,显示连接使用了何种类型,类型还是蛮多的,我选择最不理想的 ALL 类型和你解释一下,这个连接类型对于查询的表进行全表数据扫描,这种情况比较糟糕,应该尽量避免,上面的示例就进行了全表扫描。

key 表示实际使用的索引。如果为 Null,则没有使用索引,这种情况也是尤其需要注意的。

rows 表明 SQL 返回请求数据的行数,这一行非常重要,返回的内容中 SQL 遍历了 9984 行,其实也证明了这条 SQL 遍历了一张表。

关于 extra,我列举两个你需要注意的状态,因为这样的状态是会对性能产生不良的影响,意味着查询需要优化了。

**Using filesort:**表示****SQL 需要进行额外的步骤来发现如何对返回的行排序。它会根据连接类型、存储排序键值和匹配条件的全部行进行排序。

本讲相对系统地讲述了常见的 MySQL 数据库性能影响点,你可以从一个全局的角度去思考诊断 MySQL 性能问题的步骤,同时我也讲了执行计划,通过执行计划可以发现 SQL 性能问题产生的原因,这是一个非常实用的手段。

你所在的公司有没有遇到过数据库的性能问题,是怎么发现和解决的?欢迎在留言区与我分享。

下一讲我会带你继续使用执行计划带你学习导致慢 SQL 最频发的索引问题,进一步用实例来帮助你分析 SQL 索引使用常见的误区,到时见。


上节课带你学习了 MySQL 优化的整体思路,我们将优化策略逐渐进到了索引层面,性能优化其实也是这样,一般大处着眼,小处着手。这节课我将从更多的实例出发诊断 SQL 相关的问题,你可以认为是第 18 讲的补充和进阶。

上一讲已经提到过在你诊断 SQL 之前,首先要知道的是如何获取这些有问题的 SQL,一般有两种方式可以获取:

  • 从慢日志文件中获取,上一讲也描述过配置方法;

有同学留言说不知道具体应该如何使用 show full processlist,所以这里我演示下该命令的具体用法。show full processlist 可以显示哪些 SQL 线程正在运行,也可以在 MySQL 交互行下直接运行,来看下这个命令会给你展现哪些信息。

我们来解释下信息中每列的含义。

  • User:当前正在执行 SQL 的用户,只显示你登录账号权限范围内能够看到的用户。

  • Host:显示这个语句是从哪个 ID 和端口上发出的。

  • db:当前线程使用的库名。

  • Time:状态持续的时间(单位是秒)。

  • State:显示当前 SQL 语句的状态,这是一个非常重要的判断标识,比如多次刷新命令时,发现 SQL 常处于 Sending data,那么这条 SQL 大概率是存在问题的。

  • Info:显示正在执行的 SQL 语句,这也是你能直接拿到慢 SQL 的方式。

实例对比:索引对性能的影响

关于索引的基本作用通过《18 | 如何才能优化 MySQL 性能?》的内容相信你已经了解,而在性能层面更直观的影响,我想通过对比实验结果也许会更清晰一点。

我们新建了一个 user 表,表结构如下:

通过查看表信息,你可以发现我并没有添加索引,接着我使用 10 个线程测试一条SQL,其中SQL内容是通过 ID 号来查看数据,性能结果表现如下:

在 ID 列添加索引后继续基于同一条 SQL ,进行 10 线程压测,结果数据如下:

从测试结果来看,在未添加索引的情况下,TPS 是 109.4,而添加逐渐索引后,同等压力下 TPS 达到了 240.2。

CPU 资源占用如下所示:

在未添加索引的情况下,在 18:05 之前有 CPU 使用飙高,在添加索引后我在 18:10 基于同一场景测试,你会发现服务端资源使用率较低,而且 TPS 还翻了一倍以上。

通过这样一段对比,相信你能非常直观地感觉到索引带来的性能差别。

那我们是不是添加了索引就万事大吉呢,其实不是这样的,索引也有效率之分,也会存在索引失效等情况,接下来我就结合上一节课讲的执行计划来判断索引使用是否合理。有了执行计划我认为绝大多数 SQL 的问题你都可以找到优化的方向,而且对于我来说执行计划带来的直接好处是并不需要进行专门的性能测试就可以提前发现慢 SQL

继续通过执行计划来看索引的使用技巧

走索引查询数据时,如果该索引已经包含需要的数据,则称之为索引覆盖。若索引中不能拿到想要的数据,则需要通过主键拿一整行数据,这个过程叫回表,需要一次 IO 操作,所以我们写 SQL 时尽量使用索引覆盖,降低 IO 开销。

如何判断是否是索引覆盖?

首先看下 cctester 表的结构,再观察下面两个 SQL 的执行计划对比,第一个 SQL 走 name 字段,只拿 name 字段内容,第一段执行计划显示了 Using index,说明索引覆盖了;而第二个 SQL 需要额外取 mobile 字段,所以需要回表,你也可以发现第二段执行计划 Extra 列返回的 NULL,所以没有用到索引覆盖,这些细小的差别都可以通过执行计划捕捉到。

联合索引就是多个字段组成联合索引,在上一讲我们也讲过基本的作用和最左前缀规则。不过我发现一个误区,同样还是这样的一个示例 SQL,索引规则同样是 index_name(c1,c2,c3),下面这样的示例一定是符合最左前缀规则的:

那么,我改变下 SQL 的查询顺序,如下所示:

请问这样还满足最左前缀规则吗?对于 AND 这样的情况,可能很多同学觉得这个顺序和索引列不一致,应该是不满足最左前缀了,事实上不是这样的。

不管你是使用 (c1,c2,c3) 或者是 (c2,c3,c1),都是使用了联合索引,虽然表面上 (c2,c3,c1) 不符合最左前缀规则,但是 MySQL 本身是有查询优化器,它会确定这条 SQL 根据联合索引的字段顺序,最后再确定执行计划。所以说在查询字段满足条件的情况下字段顺序查询优化器是可以帮助你“纠正”的,在你项目实操过程中,对最左前缀的理解不要只局限于字面,如果你不确定可以通过执行计划来判断。

上面我举的例子是 SQL 中查询条件进行 AND 连接,看上去比较简单,我再讲一个联合索引的常用场景,看下面这样一个案例:

这里还是基于 cctester 的表结构,根据 where 条件 subject 查询之后再根据 score 排序,第一段执行计划可以看到 SQL 没有用到索引且需要额外的排序,而第二段执行计划中 SQL 使用了联合索引且不用再排序。在原理上解释就是,(subject,score,name) 索引中根据 subject 定位到的数据已经根据 score 排好顺序了,不需要再排序,这种 order by 的场景是联合索引使用最经典的案例。

索引虽好,但不代表你建了这条索引就一定会被使用,下面我列举了常用的索引失效的情况,也是日常工作中常见的一些情况。

表结构中类型是 varchar,SQL 中用的 int,这是开发最常忽略的问题,如下示例所示:

观察上面例子可以发现,score 字段是 varchar 类型,当 SQL 中忘写单引号则走不到索引,接下来我继续讲解实例,我举的例子你不用过多考虑业务特性,单纯看索引问题即可。

由于 MySQL 最左匹配原则,所以查询条件模糊开头无法命中索引,如下所示:

通过执行计划你会发现上面的情况并没有命中索引。

从上面建表结构中我们可以看到 name 字段和 score 字段都有索引,但直接写 or 查询两个字段无法使用索引,这种场景,我们可以将 or 改写成 union 即可。通过如下实例的第一段和第二段执行计划中涉及的索引项就可以看出。

本讲从实际工作出发,以慢 SQL 中问题的重灾区索引为切入点,以执行计划为手段诊断了索引的常见问题,这些都是 SQL 优化中最常见的知识点,通过实例可以让你明白这些优化带来的好处。

你还见过哪些索引未生效的情况?欢迎在评论区给出你的思考。

下一节课我将带来结束篇:线上全链路性能实践总结,虽是作为最终的 ending,还是想给你带来更多的干货,到时见。


结束语 线上全链路性能测试实践总结

作为专栏的最后一篇,我想和你聊聊线上全链路性能测试。全链路性能测试是一个非常热门的话题,不少公司也在摸索实践,这篇就以我的经验来谈谈对线上全链路性能测试的认知和实践的总结。

线上全链路性能测试提出的背景

按照我的认知,线上全链路性能测试是由阿里巴巴在 2012 年双 11 之后首次提出来的,因为当年的双 11 用户访问高峰时期系统成功率只有 50%,对于阿里同学来说,那应该是心情很沉重的双 11,复盘后发现其中的一块网卡被打满,在线下的性能测试环境中并没有发现这个问题。

为什么呢,说白了线下的压测理论上都是“缩容”测试,什么是缩容呢,就是服务器数量或者硬件配置是远低于线上的,规模容量是缩小了很多的。这导致了一些问题并不能充分被发现,实际访问量也不能很好被预估。在这样的问题背景下,线上的全链路性能测试就被提出来了。其实这和我开篇的一个观点是一致的,性能测试体系能够发展迅速,往往是公司各种大促的血泪史催化出来的,风险控制往往也能够带来最直接的生产力。

什么是线上全链路性能测试?

线上全链路性能测试就是基于真实的业务场景,实际线上环境,模拟多线程对各个业务链路进行压力测试的过程。

很多人提出了一个问题,有了线上全链路测试还需要线下性能测试吗?关于这个问题我也回答过,线上线下的性能测试理论上应当是互补的关系,线下往往权限充足而且不会对生产环境产生影响,可以发现更多的基本性能问题以及各类异常性能场景的测试,而线上是最真实的环境,对于性能验收的准确性至关重要。

什么样的情况适合全链路性能测试?

我并不认为所有的公司都适合直接进行线上性能测试,罗马不是一天建成,性能测试成熟的公司基本都经历了一段血泪史,是以一定的代价换的,对于线上全链路的开展我觉得需要几个前提:

1.已经在性能环境下进行过性能测试,但线上依然存在性能事故;

2.有频繁的促销需求,每次大促业务规则变化多;

3.对硬件成本较为敏感,需要进行容量测试,验证扩容缩容后的系统处理能力。

线上全链路性能测试聚焦的目的

相信你已经在线下进行过多轮的测试验证,线上的性能测试绝不是让你再去一遍遍执行发现基础的性能问题,线上性能测试的核心目的是验证系统的容量部署结构的优化空间整体线上的稳定性

线上全链路性能测试实施重要前提

1.评估线上全链路压测的可行性

最核心要思考的点是能不能做到压测数据的隔离,所谓数据隔离你应该能够想到的就是数据库中压测数据不能跟真实的数据混在一起,从而无法区分,比如用户数据、下单商品数据等。通用的做法是先对数据进行打标,打标的意思就是做标记,比如压测数据都会有一个能够区别于真实业务的标识,比如加 header,比如用户名基于相同的 test 开头的标记,一般对于数据隔离的方案有两种。

第一种做法就是把标记的数据进行删除,一般在压测完成之后根据标识统一清理数据,所以做标记是一个重要前提,还有个前提是你需要整理清楚涉及哪些库表,有没有依赖关系,并且做到和开发以及 DBA 确认,这样删除数据更安全。

什么是影子库表呢?简单来说就是做一个和生产一样的库表,然后把压测数据加入影子库表,这样的做法相对于清理数据的方式,后期的事情会少一点,并不需要每次都一定要清理数据。这样的做法也有一些注意点,影子库表并不是仅仅建一个空的库表,它也需要你将生产数据迁移,还有这样的做法前期工作量会大一点,需要进行中间件改造自动识别压测流量才能进入影子库表。

这两种方式各有千秋,可以根据公司的业务特性做具体的方案落地

理清核心链路流程,线上有很多的接口,所谓线上的全链路性能测试也不会把所有的接口纳入测试范围当中。我的做法是先理清楚核心的业务模块,你必须要对你的业务模块有最基本的感知,哪些是核心模块,哪些是非核心,下面我罗列一个电商基本的业务模块图。

你可以看到仅文字描述的功能就已经非常多了,如果再去细分接口,可能一张图表都放不下。你首先要考虑的就是在这些模块中,哪些是不用进行全链路性能测试的,比如类似于商家管理系统,这本身是后台系统,并不直接面向用户。同样在你确定需要测试的性能模块中进一步确定哪些接口需要进行性能测试,关于细分到接口的选择我一般将大促时的访问数据进行参考,具体的方法也有所提及。

什么是数据传输链路呢?可以想象一下你在线下压测的场景,是不是内网环境从你的压测机就直接到服务暴露出的访问接口。而线上的链路可能远比这个复杂得多,比如数据是不是首先经过防火墙、硬件层的负载均衡等,你需要把这些链路也理清楚,说白了就是要理清线上的部署架构。这也是性能测试需求分析的步骤,防火墙之类的底层结构是不会轻易变动的,但对于线上实际的应用部署节点可能变动就很多了,我们会针对不同的应用节点部署结构和数量经常调整,所以在压测之前需要前置好这些条件并记录清楚。

线上全链路性能测试实施要点

首先需要表明一些观点,很多测试人员在实际测试过程中要么是自己造数据构造场景,如果遇到一些需要开发配合的可能会被直接打回,在线上的全链路性能测试过程中可以说系统改造是必需的,线上全链路性能测试也是多团队协作完成的,并不是测试人员的“独角戏”。

很多测试同学在进行线下性能测试时,几乎是一个人完成所有的活动,包括编写脚本、压测、监控、分析等等。在开展线上全链路的时候,可能会把这一套也继续沿用,这其实是一个误区,我认为线上的性能测试相对于线下至少有三个特性。

怎么理解时间敏感呢?线上的性能测试一般都需要申请窗口期,并不是你个人决定压测就可以直接进行了,一般来说,绝大部分公司都是选择在凌晨进行,这样对实际用户的影响最小。就以测试同学来举例,线上的性能测试也有很多准备工作,测试之前会有很多试验性的工作,比如商品数据是否有效、用户 token 是否过期。一旦进行正式的压测环节,一般需要按照时间去分解任务,遇到问题讲究快速解决,需要最正确的人去做相关的任务协同,比如哪些服务集群、哪些中间件需要哪些人去监控,在有效的时间内以达到最高效率。

权限敏感很好理解,说白了你作为测试不可能像在性能测试环境一样具备充足的权限,比如可以在性能测试环境随时重启服务,增删改查数据等。作为测试在线上你不可能有这些权限,所以线上的性能测试并不是你可以自由发挥的。

说到高风险,通过其他两个特性也能看出来,如果风险不大,时间和权限自然也就没这么敏感了,所以基于风险较高,我们在线上全链路性能测试执行的时候,更希望有一个“项目经理”的角色,进行人员安排、任务同步、风险预警等,这样的角色需要深入了解性能流程以及系统的风险控制。

测试人员可以扮演的角色?

1.全链路性能测试执行者

作为一名测试执行者,你需要更关注测试本身的内容,那测试本身的内容有哪些呢?我以电商网站为例来说明,根据每家公司的业务或者体量的不同,具体的事物会有差别,但一些思路是可以借鉴的:

  • 压测机环境准备,压测机分布式节点检查;

  • 压测数据准备和检查,如会员数据、商品下单数据;

  • 脚本以及参数化文件分发;

  • 测试场景执行以及指标收集和记载。

2.线上全链路测试的“项目经理”

我刚刚也说了线上的性能测试需要一名“项目经理”,很多人思维定式认为这位项目经理需要一定级别的 leader 来担任,其实并不完全是这样。以我的思路来看,性能测试一线经验丰富的同学来承担更适合,当然这位同学不仅仅需要性能经验丰富,也需要对架构以及业务有基本盘的认知,至少做到心中有底。

如果作为一个线上全链路压测实施的“项目经理”,你需要组织什么事情呢?我用一个思维导图罗列下。

对于很多公司还是很忌惮在线上直接开始性能测试,因为觉得这样做风险太大了。这个担心是有道理的,阿里巴巴在刚刚提出这个议题时,内部也有很多不同的声音,一旦性能测试导致线上系统出现故障,轻则影响用户体验,重则系统不可用、真金白银的损失,任何人都不想为这个测试风险而买单。

虽然文章中列举了很多事项和注意点,但真正实施起来还是可能会遇到问题,所以线上性能测试的手段也是需要被测试的,比如先基于单条数据的打标、隔离、清理等,而且更需要的是发散性思维去思考,能不能把相关问题都考虑全面了,比如我之前的举例,对数据库进行数据隔离,那你有没有考虑到如 ES 数据、日志数据是否也需要做到有效的隔离呢?

在线上全链路压测过程中,报警是非常重要的,出现意外情况可以及时终止压测,防止造成额外损失。报警的规则也是需要严格制定的,硬件的、系统的、业务的,包括响应延时等都应当设置相关的阈值等,第三模块有非常详细的描述,相信你应该对监控已经比较熟悉了。

线上的全链路性能测试并不是高不可攀的技术,虽然有一定的技术门槛,但真正运作起来其实考验的是组织能力,线上全链路性能测试我认为是在线下专项性能测试上做的升级。这篇也是本专栏最终的收尾了,希望你能有所收获。

虽然本专栏已经结束了,但是后续我仍然会在微信公众号(软件测试架构师俱乐部)发表更多的知识,欢迎你来关注。

最后,我将邀请你为本专栏进行结课评价,你的每一个反馈,我和拉勾教育都会关注且认真对待。希望你能为自己的学习之旅画上一个完整的句号,,参与课程评价,编辑同学会随机抽 5 位同学送精美礼品。


我要回帖

更多关于 java第一行写什么 的文章

 

随机推荐