米哈游测试开发校招一面分享

面试题感觉不是很难,题目中规中矩,啥也没深挖, 平时就没咋背八股了,天天工作都是具体CRUD的业务,基本上靠的都是去年跳槽时候的回忆,所以答的也不是很好,感觉可能是凉了

自我介绍

为什么选择测试岗位、了解软件测试吗   

选择测试岗位的原因可能因人而异,但以下是一些常见的理由:

  1. 兴趣和技能匹配:有些人对软件测试和质量保证方面的工作感兴趣,并且拥有在这个领域发展的技能。他们可能对发现和解决问题、确保软件质量和用户体验等方面感兴趣。

  2. 重视质量:测试岗位在软件开发生命周期中起着关键作用。测试人员负责确保软件的质量,包括发现和报告缺陷、验证功能的正确性以及确保软件满足用户需求。一些人认为质量保证对于一个成功的产品至关重要,因此选择测试岗位。

  3. 分析和问题解决能力:测试人员需要具备分析和解决问题的能力。他们需要仔细分析软件的不同方面,并识别潜在的问题和风险。对于一些喜欢挑战和解决问题的人来说,测试岗位可能是一个理想选择。

  4. 多样性和变化:测试岗位通常涉及测试不同类型的软件,包括Web应用程序、移动应用程序、桌面应用程序等。这使得测试人员能够在各种不同的项目和技术中获得经验,享受不同的工作挑战和变化。

现在让我们来了解一下软件测试。

软件测试是评估和验证软件产品是否满足预期需求的过程。它旨在发现软件中的缺陷和问题,并确保软件在交付给最终用户之前达到预期的质量标准。以下是软件测试的一些关键方面:

  1. 缺陷发现:测试人员使用各种技术和工具来发现软件中的缺陷和问题。这可以包括功能测试、性能测试、安全测试等。

  2. 验证和验证:测试人员验证软件是否按照预期工作,并验证它是否满足用户需求和规格。

  3. 自动化测试:自动化测试是使用脚本和工具执行测试的过程。它可以提高测试效率和一致性,并减少人为错误。

  4. 缺陷报告和跟踪:测试人员将发现的缺陷报告给开发团队,并跟踪其修复过程,确保缺陷得到解决。

  5. 测试策略和计划:测试人员制定测试策略和计划,确定测试范围、测试方法和资源需求等。

通过软件测试,可以提高软件质量、减少风险并提供更好的用户体验。对于一个成功的软件项目,测试是不可或缺的一部分。

一个case包含哪些部分  (我能说我不会吗 直接编)

一个测试用例(test case)通常包含以下几个部分:

  1. 用例编号(Test Case ID):每个测试用例都应该有一个唯一的标识符或编号,以便于跟踪和管理。

  2. 测试场景(Test Scenario):测试场景描述了被测试的功能或业务流程的上下文和条件。

  3. 测试步骤(Test Steps):测试步骤是具体的操作序列,描述了如何执行测试用例。每个步骤都应该清晰明确,并包含必要的输入数据和操作。

  4. 预期结果(Expected Results):预期结果是对每个测试步骤执行后期望的输出、行为或状态进行描述。它指示了测试人员期望系统在特定条件下的表现。

  5. 实际结果(Actual Results):实际结果是在执行测试步骤后观察到的系统行为或输出。测试人员将实际结果与预期结果进行对比,以确定测试是否通过或失败。

  6. 测试数据(Test Data):测试数据是用于执行测试用例的输入数据。它应该包括各种可能的情况,包括边界值、无效数据、特殊字符等。

  7. 前置条件(Preconditions):前置条件是指在执行测试用例之前需要满足的条件或状态。它确保系统处于适当的环境中以执行测试。

  8. 后置条件(Postconditions):后置条件是指在执行测试用例后期望的系统状态或结果。它描述了测试用例执行完成后系统应该处于的状态。

  9. 优先级(Priority):优先级标识了测试用例的重要程度和执行顺序。根据项目需求和时间限制,可以将测试用例分配为高、中、低优先级等级。

  10. 测试状态(Test Status):测试状态跟踪测试用例的执行情况,例如“通过”、“失败”、“阻塞”等。

以上是测试用例常见的部分,根据具体的测试流程和项目要求,有时还可能包含其他信息,例如测试环境、备注、关联的缺陷等。编写清晰、准确和完整的测试用例对于有效执行软件测试非常重要。

​现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:485187702【暗号:csdn11】

tcp和udp的区别

TCP(Transmission Control Protocol)和UDP(User Datagram Protocol)是互联网协议栈中的两个常见的传输层协议,它们具有以下区别:

  1. 连接导向 vs 无连接:TCP是一种连接导向的协议,它在通信之前需要建立连接,并提供可靠的、面向字节流的传输。UDP是一种无连接的协议,它不需要建立连接,每个数据报都是独立的。

  2. 可靠性:TCP提供可靠的数据传输,它使用序号、确认和重传机制来确保数据的完整性和顺序性。如果数据丢失或损坏,TCP会自动重传丢失的数据。UDP不提供可靠性保证,它将数据报发送出去,但不关心数据是否到达目标,也不进行重传。

  3. 有序性:TCP保证数据按照发送的顺序到达目标,接收方将按照发送顺序重新组装数据。UDP不保证数据的有序性,接收方收到数据报后可以以任意顺序处理。

  4. 流量控制和拥塞控制:TCP具有流量控制和拥塞控制机制,它可以调整发送方的发送速率以适应网络的负载情况,避免网络拥塞。UDP没有内置的流量控制和拥塞控制机制,数据包发送速度由应用程序决定。

  5. 开销:TCP协议的额外功能和保证可靠性的机制增加了协议的开销。UDP相对简单,没有额外的开销,使其在某些实时应用和对时延敏感的应用中更常见。

  6. 适用场景:TCP适用于需要可靠性和顺序性的应用,例如文件传输、电子邮件、网页浏览等。UDP适用于实时性要求较高、对时延敏感的应用,例如音频/视频传输、实时游戏等。

总结起来,TCP提供可靠的、面向连接的通信,而UDP提供简单的、无连接的通信。选择使用TCP还是UDP取决于应用程序的需求和对性能和可靠性的权衡。

http状态码

老八股文了都,一次性补全网络基础知识!

DNS的解析过程

DNS(Domain Name System)解析是将域名(例如www.example.com)转换为相应的IP地址的过程。下面是DNS解析的基本过程:

  1. 发送DNS查询:当用户在浏览器中输入一个域名时,操作系统的DNS解析器首先检查本地DNS缓存,如果缓存中存在对应的IP地址,则直接返回结果。如果缓存中没有记录或已过期,解析器将发送DNS查询请求。

  2. 本地DNS服务器:如果解析器没有缓存记录或缓存过期,它将向本地DNS服务器发送查询请求。本地DNS服务器通常由Internet服务提供商(ISP)提供,并由解析器的配置设置确定。本地DNS服务器维护着一些常见域名的缓存记录,它可能会返回缓存中的IP地址作为响应,如果缓存中没有记录,它将继续向上层DNS服务器发起查询。

  3. 递归查询:本地DNS服务器在收到查询请求后,如果它没有缓存记录,它将根据自己的配置进行递归查询。它向顶级域名服务器(例如.com域的顶级域名服务器)发送查询请求,并询问它们掌管的下一级域名服务器的IP地址。

  4. 迭代查询:顶级域名服务器收到查询请求后,它将返回下一级域名服务器的IP地址给本地DNS服务器。本地DNS服务器将向下一级域名服务器发起查询,并继续这个过程直到找到负责解析目标域名的权威域名服务器。

  5. 权威域名服务器:当本地DNS服务器找到负责解析目标域名的权威域名服务器后,它将向该服务器发送查询请求。

  6. 返回查询结果:权威域名服务器收到查询请求后,它将返回解析后的IP地址给本地DNS服务器。

  7. 响应返回:本地DNS服务器收到解析结果后,它将把结果存储在缓存中,并将解析结果发送给操作系统的DNS解析器。解析器将结果传递给应用程序,例如浏览器,使其能够建立与目标服务器的连接。

上述过程中,DNS解析可能会经过多个级别的域名服务器,从顶级域名服务器到权威域名服务器。为了提高解析效率,DNS解析结果通常会在本地DNS服务器和操作系统的DNS解析器中进行缓存,以便在将来的查询中快速响应。

为什么要三次握手

三次握手是TCP(Transmission Control Protocol)建立连接的过程,它的设计目的是为了确保双方能够正常通信并同步初始序列号。以下是三次握手的原因和作用:

  1. 双方确认能够通信:通过三次握手,客户端和服务器能够互相确认彼此的存在并且能够相互通信。每次握手都要求对方确认,确保双方的通信路径是可达的。

  2. 同步初始序列号(ISN):在TCP连接建立时,每个端点都会选择一个初始序列号。通过三次握手,客户端和服务器可以交换彼此的初始序列号,以便在数据传输过程中正确地识别和重组数据。

  3. 避免旧连接的影响:在网络中,旧的连接可能仍然存在于网络中,如果没有进行三次握手,新的连接请求可能会被误认为是旧连接的延迟报文。通过三次握手,可以确保旧连接已经被终止,并且避免了对新连接的干扰。

  4. 确保可靠性:三次握手可以帮助检测到连接建立过程中的错误或问题,例如网络延迟、丢包或无法到达的目标主机等。如果握手过程中发生错误,客户端和服务器可以重新尝试建立连接,确保连接的可靠性。

总之,通过三次握手,TCP能够建立可靠的连接,确保通信双方能够正常交换数据,并保证连接的可靠性和正确性。每个握手阶段都承担着重要的功能,确保连接的成功建立和同步序列号的准确性。

为什么要四次挥手

四次挥手是TCP(Transmission Control Protocol)断开连接的过程,它的设计目的是确保双方都能正确终止连接并释放相关资源。以下是四次挥手的原因和作用:

  1. 双方完成数据传输:在断开连接之前,双方可能还有剩余的数据需要传输完毕。通过四次挥手,双方可以确认彼此已经完成了数据传输,避免了数据的丢失或被截断。

  2. 确保可靠的关闭:TCP是一种可靠的传输协议,它保证数据的可靠性和有序性。通过四次挥手,可以确保连接的关闭也是可靠的,并防止在关闭过程中的数据丢失或重复。

  3. 延迟报文的处理:在连接关闭之前,可能仍然存在在网络中未传输完毕的延迟报文。通过四次挥手,双方可以等待一段时间以确保网络中的延迟报文都已被处理,从而避免后续产生的混乱或冲突。

  4. 释放连接资源:通过四次挥手,双方可以通知对方它们不再需要连接,并释放相关的资源,例如TCP缓冲区、序列号等。这样可以使得网络资源能够被及时回收和重用。

需要注意的是,四次挥手是由主动关闭连接的一方(通常是客户端)发起的,而被动关闭连接的一方(通常是服务器)只是响应关闭请求。四次挥手的每个阶段都承担着重要的功能,确保连接的正常关闭和资源的释放。

总之,通过四次挥手,TCP能够实现可靠的连接断开过程,确保数据的完整性和正确性,并释放连接相关的资源,使得网络能够高效地管理连接和资源分配。

TCP为什么传输是可靠的    (基于数据块传输)

TCP(Transmission Control Protocol)之所以被称为可靠的传输协议,是因为它在数据传输过程中提供了多种机制来确保数据的可靠性和有序性。

以下是TCP实现可靠传输的主要机制:

  1. 序列号和确认应答:TCP将每个数据包分配一个唯一的序列号,并通过接收方的确认应答机制来确认收到的数据包。发送方可以根据确认应答来确定哪些数据包已经成功到达接收方,以及哪些数据包需要进行重传。

  2. 数据段重传:如果发送方没有收到对特定数据段的确认应答,它会认为该数据段丢失,并进行重传。接收方可以根据序列号来判断是否收到重复的数据段,并丢弃重复的数据。

  3. 滑动窗口协议:TCP使用滑动窗口协议来管理发送和接收的数据段。通过滑动窗口,发送方可以控制发送的数据量,并根据接收方的处理能力进行调整。滑动窗口协议还允许发送方在等待确认应答时继续发送其他数据,提高传输效率。

  4. 拥塞控制:TCP使用拥塞控制算法来避免网络拥塞。它通过监测网络的负载情况和接收到的确认应答来调整发送速率。拥塞控制算法包括慢启动、拥塞避免和拥塞恢复等机制,以保持网络的稳定性和公平性。

  5. 有序交付:TCP确保数据按照发送的顺序到达接收方,并在接收方重新组装数据,以便上层应用能够正确处理数据。

通过这些机制,TCP可以应对网络中的丢包、延迟、重复、乱序等问题,提供可靠的数据传输。它能够自动重传丢失的数据,调整发送速率以适应网络状况,并保证数据的有序性。这使得TCP成为广泛应用于可靠数据传输的协议,例如文件传输、电子邮件、网页浏览等。

NAT协议和跨域了解吗

我了解NAT协议和跨域的概念,下面对它们进行简要说明:

  1. NAT(Network Address Translation,网络地址转换):NAT是一种网络协议,用于将私有网络中的内部IP地址和端口映射到公共网络中的公网IP地址和端口。它允许多个设备共享单个公网IP地址,提供了一种解决IPv4地址短缺问题的方法。NAT工作在网络层,它在数据包经过网络边界设备(如路由器)时,修改源IP地址和目标IP地址,以实现内部私有地址和外部公网地址之间的转换。

  2. 跨域(Cross-Origin):跨域指的是在浏览器中,当一个网页的脚本试图访问不同源(域名、端口、协议)的资源时,就发生了跨域请求。出于安全原因,浏览器默认限制了跨域请求的访问,这是浏览器的同源策略所导致的。为了在跨域请求中进行通信,需要使用一些特定的技术和安全措施,如跨域资源共享(CORS)机制、JSONP(JSON with Padding)、代理服务器等。

需要注意的是,NAT协议和跨域是两个不同的概念,涉及到不同的网络和安全领域。NAT主要用于网络通信中的地址转换,解决IPv4地址短缺问题;而跨域是浏览器安全策略的一部分,用于限制脚本在不同源之间的通信。

get和post的区别

GET和POST是HTTP协议中常用的两种请求方法,它们之间存在以下区别:

  1. 数据位置:GET请求将参数包含在URL的查询字符串中,而POST请求将参数包含在请求的消息体中。在GET请求中,参数会暴露在URL中,可以被缓存、书签等直接可见,而POST请求的参数不会直接显示在URL中。

  2. 数据长度限制:由于GET请求将参数包含在URL中,URL长度有限制,因此GET请求对传输的数据长度有限制(通常在几千个字符之内)。而POST请求将参数包含在消息体中,通常没有严格的长度限制。

  3. 安全性:GET请求的参数在URL中可见,容易被第三方获取,包括敏感信息,因此不适合传输敏感数据。POST请求将参数放在消息体中,相对于GET请求更安全,适合传输敏感数据。

  4. 缓存:GET请求可以被缓存,而POST请求默认不会被缓存。由于GET请求的参数直接暴露在URL中,响应结果也可以被缓存,这对于一些幂等的请求(不产生副作用)是合理的。POST请求往往用于提交表单或进行数据修改,每次请求都应该向服务器发送最新的数据,避免产生副作用。

  5. 幂等性:GET请求是幂等的,即多次相同的GET请求应该产生相同的结果,不会对资源产生副作用。而POST请求往往用于对资源进行修改或创建,可能会产生副作用,不具备幂等性。

总的来说,GET请求适合用于获取数据,对于无副作用的请求,而POST请求适合用于提交数据、修改数据,以及对资源进行操作。根据具体的场景和需求,选择适合的请求方法。

线程的状态

线程在执行过程中会经历多个状态,常见的线程状态包括:

  1. 新建(New):线程被创建但还未开始执行。

  2. 可运行(Runnable):线程被启动后,进入可运行状态。它表示线程可以被调度执行,但并不一定正在执行,可能正在等待CPU的分配时间。

  3. 运行(Running):线程获得CPU资源,正在执行任务。

  4. 阻塞(Blocked):线程在某些条件下被挂起,暂时停止执行。例如,线程正在等待某个锁的释放或等待输入/输出完成。

  5. 等待(Waiting):线程被要求等待,直到其他线程发出特定的通知。它会一直等待,直到接收到通知或者被中断。

  6. 计时等待(Timed Waiting):类似于等待状态,但是可以在指定的时间内自动唤醒。线程会等待一段时间,直到时间到达或者接收到通知或者被中断。

  7. 终止(Terminated):线程执行完任务或者发生异常而结束。

需要注意的是,不同的编程语言和操作系统对线程状态的具体实现可能有所不同,上述状态仅为常见的线程状态概念。此外,线程状态之间可以相互转换,比如从可运行状态到运行状态,或者从运行状态到阻塞状态,这取决于线程调度和程序的执行流程。

什么是死锁、死锁的条件

死锁(Deadlock)是多线程或多进程并发编程中的一种常见情况,指的是两个或多个线程(或进程)因互相等待对方释放资源而无法继续执行的状态,导致系统无法前进或完成任务。在死锁状态下,线程将永远等待下去,除非外部干预。

死锁通常发生在满足以下四个必要条件的情况下:

  1. 互斥条件(Mutual Exclusion):至少有一个资源同时只能被一个线程(或进程)占用,其他线程无法同时访问该资源。

  2. 请求与保持条件(Hold and Wait):线程在持有至少一个资源的同时,又请求其他线程当前正占用的资源。

  3. 不可剥夺条件(No Preemption):资源只能在线程自愿释放的情况下才能被其他线程获取,无法被强制剥夺。

  4. 循环等待条件(Circular Wait):存在一组线程,每个线程都在等待下一个线程所占用的资源,形成一个循环等待的闭环。

当这四个条件同时满足时,就有可能发生死锁。一旦发生死锁,系统将无法自动解除死锁状态,需要人为干预或采取相应的死锁处理机制。

为避免死锁的发生,常见的死锁处理方法包括:

  1. 资源有序分配:为资源定义一个全局顺序,并要求线程按照相同的顺序请求资源,避免循环等待条件的发生。

  2. 避免请求和保持:线程在请求资源时,先释放已经持有的资源,然后再申请新的资源,以避免持有资源的冲突。

  3. 引入抢占机制:允许系统在某些情况下强制剥夺某个线程的资源,以满足其他线程的需求。

  4. 死锁检测与恢复:通过算法检测系统中是否存在死锁,如果检测到死锁,采取相应的策略进行恢复,如剥夺某些线程的资源或重新分配资源等。

了解死锁及其条件有助于编写并发程序时避免死锁发生,并能够选择合适的死锁处理策略。

进程通信的方式有哪些

在多进程编程中,进程之间需要进行通信以交换数据和协调工作。常见的进程通信方式包括:

  1. 管道(Pipe):管道是最简单的进程间通信机制,分为无名管道和有名管道。无名管道只能在具有父子关系的进程之间使用,而有名管道允许无关的进程进行通信。

  2. 命名管道(Named Pipe):也称为FIFO(First-In-First-Out),是一种特殊类型的文件,允许无关的进程进行通信。不同于无名管道,命名管道可以在不具有亲缘关系的进程之间使用。

  3. 信号量(Semaphore):信号量用于控制多个进程对共享资源的访问。它可以用来实现进程的互斥和同步。

  4. 信号(Signal):信号是一种异步通信机制,用于通知进程发生了某种事件。一个进程可以发送信号给另一个进程,接收到信号的进程可以采取相应的动作。

  5. 消息队列(Message Queue):消息队列是一种进程间通信的方式,进程可以通过消息队列发送和接收消息。消息队列中的消息可以按照特定的优先级排序。

  6. 共享内存(Shared Memory):共享内存是最快的进程间通信方式,它允许多个进程共享同一块物理内存区域,进程可以直接读写共享内存中的数据。

  7. 套接字(Socket):套接字是一种提供网络通信能力的进程间通信机制,它可以在不同主机之间的进程进行通信。

这些进程通信方式各有优缺点,适用于不同的场景和需求。在选择进程通信方式时,需要根据具体情况综合考虑各种因素,如性能要求、数据大小、安全性等。

linux常见命令

  1. ls:列出目录内容。

  2. cd:切换当前工作目录。

  3. pwd:显示当前工作目录的路径。

  4. mkdir:创建新目录。

  5. rm:删除文件或目录。

  6. cp:复制文件或目录。

  7. mv:移动文件或目录,或者重命名文件。

  8. touch:创建新文件或更新文件的访问和修改时间。

  9. cat:连接文件并打印到标准输出。

  10. less:查看文本文件内容,支持上下滚动和搜索。

  11. grep:在文件中搜索指定的模式。

  12. find:在文件系统中搜索文件。

  13. chmod:修改文件或目录的权限。

  14. chown:修改文件或目录的所有者。

  15. chgrp:修改文件或目录的所属组。

  16. ps:显示当前运行的进程状态。

  17. top:动态显示系统资源使用情况和进程信息。

  18. kill:发送信号给指定进程。

  19. tar:归档和解压缩文件。

  20. wget:从网络下载文件。

  21. ifconfig:显示和配置网络接口信息。

  22. ping:向指定主机发送网络请求以测试连接。

  23. ssh:远程登录到另一台计算机。

  24. scp:在本地和远程计算机之间复制文件。

  25. man:查看命令的手册页。

一条修改数据的sql语句 uptate

UPDATE table_nameSET column1 = value1, column2 = value2, ...WHERE condition;

其中:

  • table_name 是要修改数据的表名。

  • column1column2, ... 是要更新的列名。

  • value1value2, ... 是要更新的新值。

  • condition 是一个可选的条件,用于指定要更新的行的筛选条件。

B+树的优点(为什么要用B+树做索引)

B+树是一种常用的数据结构,被广泛应用于数据库系统中的索引实现。使用B+树作为索引结构具有以下优点:

  1. 高效的范围查询:B+树是一种平衡树,它的叶子节点通过链表连接,使得范围查询变得高效。在B+树上进行范围查询只需要对叶子节点进行顺序遍历,而无需遍历整棵树,因此范围查询的性能较好。

  2. 高度平衡的树结构:B+树保持了树的平衡性,每个节点的深度差异较小,因此对于任意给定的数据集,查询的性能可以得到保证。相比于二叉树或者平衡二叉树,B+树的高度更低,减少了磁盘I/O访问次数。

  3. 数据的顺序访问:B+树的内部节点不存储数据,只存储索引,而叶子节点按照顺序存储数据,提供了顺序访问的优势。对于范围查询或者顺序遍历操作,可以利用磁盘预读机制,一次性读取一片连续的叶子节点,提高访问效率。

  4. 支持快速插入和删除:B+树的插入和删除操作相对较快,因为它只需要调整路径上的几个节点即可。而且由于B+树节点的大小通常与磁盘页的大小相适应,插入和删除操作的影响范围较小。

  5. 适应大数据集和高并发访问:B+树适用于存储大量的数据和高并发的访问场景。它的结构能够提供较好的读写性能,并且支持并发操作,多个事务可以同时访问不同的叶子节点,提高了系统的并发性能。

综上所述,B+树的优点包括高效的范围查询、高度平衡的树结构、数据的顺序访问、快速的插入和删除操作以及适应大数据集和高并发访问的能力,这些特点使得B+树成为数据库索引的一种重要选择。

脏读、幻读、不可重复读的区别

脏读(Dirty Read),幻读(Phantom Read)和不可重复读(Non-repeatable Read)是数据库中并发操作可能出现的问题,描述了不同的读取数据的现象。

  1. 脏读(Dirty Read):脏读指的是一个事务读取了另一个事务未提交的数据。当一个事务对数据进行了修改,但还未提交时,另一个事务读取了这个未提交的数据。如果未提交的事务最终被回滚,那么读取到的数据就是无效的。脏读可能会导致数据的不一致和错误的判断。

  2. 幻读(Phantom Read):幻读指的是一个事务在读取数据时,另一个事务插入(或删除)了满足同样条件的新数据,导致第一个事务后续的读取发现了之前不存在的数据。幻读通常发生在使用范围查询时,如果在读取期间有其他事务插入了符合查询条件的数据,就会出现幻读。

  3. 不可重复读(Non-repeatable Read):不可重复读指的是在同一个事务中,两次读取同一行数据时,得到的结果不一致。不可重复读通常发生在并发环境下,当一个事务多次读取同一行数据,而其他事务在这之间修改或删除了该行数据,导致第一个事务读取到的数据不一致。

区别:

  • 脏读是指读取了未提交的数据,幻读和不可重复读都是在已提交的数据中发生的现象。

  • 脏读关注的是未提交的数据的读取,而幻读和不可重复读关注的是已提交的数据的读取。

  • 幻读主要涉及到数据的插入和删除操作,而不可重复读主要涉及到数据的修改操作。

这些问题的出现主要与并发事务的隔离级别有关,不同的隔离级别会产生不同的并发读取问题。为了避免这些问题,可以采用合适的事务隔离级别、锁机制和并发控制策略来保证数据的一致性和准确性。

事务的ACID机制

事务的 ACID 是指数据库管理系统中保证事务正确执行的四个特性:

  1. 原子性(Atomicity):事务被视为一个不可分割的原子操作,要么全部执行成功,要么全部失败回滚。如果事务中的任何操作失败,整个事务将被回滚到初始状态,不会留下部分完成的结果。

  2. 一致性(Consistency):事务的执行使数据库从一个一致状态转换到另一个一致状态。事务在开始和结束时,数据库必须满足定义的完整性约束,包括数据的唯一性、关系的完整性、域约束等。

  3. 隔离性(Isolation):并发执行的事务相互隔离,使它们互不干扰。每个事务都应该感觉到它是在独立运行的,即使有其他事务在同时执行。隔离性防止了并发事务之间的相互干扰,避免了数据不一致性的问题。

  4. 持久性(Durability):一旦事务成功提交,其结果应该永久保存在数据库中,即使系统发生故障。持久性确保事务的结果在系统恢复后仍然可用,通常通过将事务的操作记录到磁盘上的日志文件来实现。

这些 ACID 特性确保了事务的可靠性和数据的一致性。数据库管理系统通过使用锁机制、并发控制、事务日志和回滚机制等技术来实现这些特性,以保证事务的正确执行和数据的可靠性。

Redis常用的数据类型

Redis(Remote Dictionary Server)是一种基于内存的键值存储数据库系统,它支持多种数据类型。以下是 Redis 常用的数据类型:

  1. 字符串(String):字符串是 Redis 最基本的数据类型,可以存储文本、整数或二进制数据。

  2. 哈希(Hash):哈希是一个键值对的集合,类似于关联数组。每个哈希可以存储多个字段和对应的值,适合存储对象。

  3. 列表(List):列表是一个有序的字符串集合,可以在列表的两端进行元素的插入和删除操作,适合实现队列和栈等数据结构。

  4. 集合(Set):集合是一个无序的字符串集合,每个集合中的元素都是唯一的。支持集合的交、并、差等集合操作。

  5. 有序集合(Sorted Set):有序集合是一个有序的字符串集合,每个元素都与一个分数相关联,通过分数来排序集合中的元素。支持根据分数范围进行检索和排名等操作。

  6. Bitmaps:位图是一个由二进制位组成的数据结构,可以对二进制位进行操作,如设置、清除、计数等。

  7. HyperLogLog:HyperLogLog 是一种基数估计算法,用于统计元素的唯一数量,适用于统计大规模数据的基数。

  8. 地理位置(Geospatial):Redis 提供了对地理位置的支持,可以存储地理坐标,并进行距离计算和范围查询。

这些数据类型使得 Redis 可以灵活地应用于不同的场景,如缓存、消息队列、计数器、排行榜等。根据具体的需求,选择适当的数据类型可以更高效地使用 Redis 的功能和性能。

算法题  去除字符串头尾的空格  (不能用已有的方法)

public class TrimSpaces {    public static String trimSpaces(String s) {        if (s == null || s.length() == 0) {            return "";        }                int start = 0;        int end = s.length() - 1;
        // 移动头指针,直到遇到第一个非空格字符        while (start <= end && s.charAt(start) == ' ') {            start++;        }
        // 移动尾指针,直到遇到第一个非空格字符        while (start <= end && s.charAt(end) == ' ') {            end--;        }
        // 构造去除空格后的子串        StringBuilder result = new StringBuilder();        for (int i = start; i <= end; i++) {            result.append(s.charAt(i));        }
        return result.toString();    }
    public static void main(String[] args) {        String s = "   Hello, World!   ";        String trimmed = trimSpaces(s);        System.out.println(trimmed);    }}

测试微信发红包功能  (巴拉巴拉说了一堆,感觉人家已经开始不耐烦了)

针对微信发红包功能,可以设计以下测试用例来验证其功能和性能:

  1. 正常发送红包:输入有效的金额和接收者,验证红包能够成功发送,并且接收者能够收到红包金额。

  2. 发送空金额红包:尝试发送红包时金额输入为空或为零,验证系统是否能够正确提示金额无效的错误信息。

  3. 发送负金额红包:尝试发送红包时金额输入为负数,验证系统是否能够正确提示金额无效的错误信息。

  4. 发送超过账户余额的红包:尝试发送红包时金额超过账户的可用余额,验证系统是否能够正确提示余额不足的错误信息。

  5. 发送给不存在的用户:尝试发送红包给一个不存在的用户,验证系统是否能够正确提示用户不存在的错误信息。

  6. 发送红包时网络异常:模拟网络异常情况下发送红包,验证系统是否能够正确处理并提示网络错误。

  7. 大规模并发发送红包:模拟多个用户同时发送红包,验证系统在高并发情况下的性能和稳定性。

  8. 发送拼手气红包:发送拼手气红包给多个接收者,验证系统是否能够正确计算和分配红包金额。

  9. 发送定时红包:设置定时发送红包的时间,验证系统是否能够准时发送红包。

  10. 发送红包后查看红包记录:发送红包后查看红包记录,验证系统是否正确记录发送的红包信息。

以上测试用例涵盖了一些常见的功能和边界情况,可以帮助验证微信发红包功能的正确性、可靠性和性能。根据具体的需求和业务场景,还可以进一步设计更多的测试用例来覆盖更多的功能和场景。

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走! 希望能帮助到你!【100%无套路免费领取】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值