作者:Bruce.D
github:https://github.com/doukoi-BDB
文章底部有【技术社群&福利】,不定更新活动、源码,欢迎来撩~~~
今日主题:
1、2024年技术面试梳理(沟通40位技术面试&面试官);
2、预计阅读 30分钟,字数:11234 字(长篇汇总)
3、兄弟们想打卡sql 领取积分兑换🎁,因此我的小程序正在抓紧研发中,预计端午后可以出来第一版本~~~
你了解 PHP 8 的新特性吗?请列举一些 PHP 8 的新功能。
01
Just-In-Time (JIT) 编译:PHP 8 包含了一个 JIT 编译器,它可以提高应用程序的性能,尤其是计算密集型的应用程序。通过将 PHP 代码转换成直接可在硬件上运行的机器码,JIT 编译器能显著提高执行效率。
命名参数:PHP 8 允许在调用函数时使用参数的名字,而不是仅依赖参数的位置。这使得代码更清晰,也更容易理解。
属性构造器:引入了构造函数属性 Promotion,这个功能可以简化类的构造函数的代码。你可以在构造函数声明中直接定义类的属性,避免了重复代码。
match 表达式:match 是对 switch 语句的改进,语法更加简洁,且自动具有严格类型检查和返回值。
空安全运算符 ??=:这个新的运算符允许你在尝试赋值前检查变量是否为 null。如果不是 null,则使用原有值;如果是 null,则使用指定的默认值。
混合类型声明:PHP 8 允许函数和方法参数、返回值使用 mixed 类型,这表示参数可以是任何类型。
throw 表达式:在 PHP 8 中,throw 成为了一个表达式而不仅是一个语句。这意味着它可以在更多地方使用,例如在箭头函数中。
Trailing comma in parameter lists:现在函数定义中的参数列表末尾可以包含一个逗号,这在以前的版本中是不允许的。
Weak maps:弱引用集合,用于存储对象作为键的数据,而不会阻止对象被垃圾收集。
类型系统和错误处理的改进:PHP 8 提高了类型系统的严格性,并改进了错误处理,使得代码更加健壬且易于维护。
PHP 中的接口和抽象类有什么区别?
02
-
定义方式:
接口:接口定义了一组方法的契约,但不包含方法的实现。接口中的方法只有方法签名,没有方法体。
抽象类:抽象类可以包含抽象方法(即只有方法签名但没有方法体),也可以包含具体的方法实现。
继承:
接口:一个类可以实现多个接口,通过使用 implements 关键字来实现接口,并且需要实现接口中定义的所有方法。
抽象类:子类只能继承一个抽象类,通过使用 extends 关键字来继承抽象类,并且需要实现抽象类中的所有抽象方法。
方法的可见性:
接口:接口中的所有方法默认为公共(public),因为它们必须在实现类中公开实现。
抽象类:抽象类中的方法可以具有不同的可见性修饰符(public、protected 或 private)。
构造函数:
接口:接口不能包含构造函数。
抽象类:抽象类可以包含构造函数。
多态性:
接口:接口提供了更大的灵活性,因为一个类可以实现多个接口,从而可以应对更多的场景。
抽象类:抽象类更适合用于某个类的基本实现,以提供公共的功能和属性。
总的来说,接口更适合定义对象的行为,而抽象类更适合用于某个类的基本实现。
解释 PHP 中的内存泄漏是什么,并提供避免内存泄漏的方法。
03
内存泄漏是指程序在运行过程中,由于错误的内存管理导致未使用的内存得不到释放,最终导致系统内存资源耗尽的现象。
在 PHP 中,内存泄漏通常是由以下情况引起的:
循环引用:当两个或多个对象相互引用,并且没有被其他对象引用,这种情况可能导致内存泄漏,因为 PHP 的垃圾回收机制无法回收被循环引用的对象。
未关闭的资源:如果在使用完文件、数据库连接或其他资源后没有显式关闭它们,这些资源可能会继续占用内存,导致内存泄漏。
全局变量:全局变量的生命周期长,如果没有正确管理,可能会导致内存泄漏。
为避免内存泄漏,可以采取以下方法:
-
避免循环引用:确保对象之间的引用关系不会形成循环。可以通过在不需要使用某个对象时将其设置为 null 来打破循环引用。
显式关闭资源:在使用完文件、数据库连接或其他资源后,应该显式调用相关的关闭方法或释放资源。
限制全局变量的使用:尽量减少全局变量的使用,避免过多的全局变量导致内存占用过高。
使用 unset() 函数:在不再需要某个变量时,可以使用 unset() 函数将其从内存中删除。
优化代码:编写高效的代码,尽量避免创建过多的对象和数组,以减少内存占用。
使用缓存:合理使用缓存机制,避免重复创建相同的对象或数据结构。
定期检查和优化:定期检查代码,查找潜在的内存泄漏问题,并对代码进行优化和改进。
redis删除策略讲一下
04
Redis 中的删除策略用于在内存使用达到最大限制时决定要删除哪些键以释放空间。常见的删除策略包括:
-
volatile-ttl:优先删除设置了过期时间(TTL)的键,并且删除剩余时间最短的键。
volatile-lru:优先删除最近最少使用(LRU)的键,但仅限于设置了过期时间的键。
volatile-random:随机删除设置了过期时间的键。
allkeys-lru:优先删除最近最少使用的键,无论是否设置了过期时间。
allkeys-random:随机删除任意键,无论是否设置了过期时间。
这些策略可以在 Redis 的配置文件中通过 maxmemory-policy 参数来指定,默认为 volatile-lru。
mysql的cpu过大怎么优化
05
-
优化查询语句:分析数据库的查询语句,并使用合适的索引来加速查询。通过 EXPLAIN 命令来查看查询执行计划,找出慢查询并优化。
优化数据库设计:合理设计数据库表结构,避免过度范式化和冗余数据,以提高查询效率。
优化服务器参数:调整 MySQL 服务器的配置参数,例如增加缓冲区大小、线程数等,以提高系统性能。
使用缓存:利用缓存技术(如 Redis 或 Memcached)缓存频繁访问的数据,减少对数据库的访问压力。
分析慢查询日志:分析 MySQL 的慢查询日志,找出耗时较长的查询,并进行优化。
升级硬件:如果可能的话,考虑升级硬件,包括 CPU、内存和存储设备,以提升系统整体性能。
使用主从复制:将读写分离,将读操作分摊到多个服务器上,减轻单一服务器的压力。
定期维护:定期进行数据库的优化和维护,包括索引重建、碎片整理等操作。
http请求发现好多time_wait怎么处理
06
TCP 的 TIME_WAIT 状态是指在关闭连接后,保持连接的一种状态,以确保在连接关闭之后的一段时间内不会出现重复的连接。TIME_WAIT 状态的持续时间由操作系统内核参数决定,通常为 2 * MSL(Maximum Segment Lifetime)。
如果发现大量的 TIME_WAIT 状态连接,可以考虑以下一些处理方法:
-
调整内核参数:可以通过调整操作系统的内核参数来缩短 TIME_WAIT 状态连接的持续时间,例如减小 MSL 参数。
调整连接超时时间:在应用程序中,可以调整连接的超时时间,尽早关闭连接,从而减少进入 TIME_WAIT 状态的连接数量。
增加服务器资源:如果服务器资源允许,可以增加服务器的内存和处理器等资源,以处理更多的连接。
使用连接池:使用连接池技术可以有效地重用连接,减少连接的创建和关闭次数,从而减少 TIME_WAIT 状态的连接数量。
使用负载均衡:使用负载均衡器将请求分发到多台服务器上,可以减少单台服务器上的连接数量,从而减少 TIME_WAIT 状态连接的影响。
优化网络拓扑:优化网络拓扑结构,减少网络延迟和丢包率,可以降低连接的建立和关闭时间,减少 TIME_WAIT 状态连接的数量。
如何防止大流量进来导致页面加载过慢&奔溃
07
防止大流量进来导致页面加载过慢或奔溃是一个常见的挑战,特别是在应对突发性的流量激增时。以下是一些可以采取的措施:
负载均衡器:使用负载均衡器来分发流量到多台服务器上,以平衡服务器的负载,防止单台服务器过载而导致页面加载缓慢或奔溃。
缓存技术:利用缓存技术(如 CDN、Redis、Memcached 等)缓存静态资源和频繁访问的数据,减少服务器的负载,提高页面加载速度。
优化页面资源:优化页面资源,包括压缩图片、合并和压缩 CSS、JavaScript 文件等,以减少页面加载时间。
限流:在应用程序或服务器上实现限流机制,控制请求的数量和速率,避免过多的请求导致服务器崩溃或响应缓慢。
预留资源:为应对流量激增,提前预留一定的资源(如服务器、带宽等),以应对突发性的流量增加。
自动扩展:使用自动扩展技术,根据实际负载情况动态增加或减少服务器实例,以满足流量的变化需求。
监控和报警:建立监控系统,实时监控服务器的负载、流量等指标,设置相应的报警规则,及时发现并解决潜在的问题。
优化数据库:优化数据库的查询和索引,提高数据库的性能和吞吐量,避免数据库成为瓶颈导致页面加载缓慢或奔溃。
全链路追踪介绍
08
全链路追踪(distributed tracing)是一种用于监控和诊断分布式应用程序性能的技术。它允许开发人员跟踪分布式系统中的请求在不同组件之间的传播和处理情况,从而帮助他们理解系统的整体性能,并找出潜在的瓶颈和问题。
全链路追踪通常涉及以下几个关键概念和组件:
追踪器(Tracer):追踪器是全链路追踪系统的核心组件,负责记录请求在系统中的传播路径和各个组件的处理情况。它会为每个请求生成一个唯一的标识符,并在整个请求处理过程中将这个标识符传递给各个组件。
跨越多个组件的唯一标识符(Trace ID):Trace ID 是一个唯一的标识符,用于跟踪一个请求在系统中的传播路径。在请求进入系统时,追踪器会为其生成一个 Trace ID,并在请求的处理过程中将这个 Trace ID 传递给每个组件。
跨越单个组件内的唯一标识符(Span ID):Span ID 是一个唯一的标识符,用于表示一个请求在单个组件内的处理情况。每个组件在处理请求时都会创建一个或多个 Span,并将这些 Span 的信息发送给追踪器。
上下文传递:追踪器通过上下文传递机制,将 Trace ID 和 Span ID 传递给系统中的各个组件,使它们能够将自己的处理情况与整个请求的处理过程关联起来。
可视化界面:全链路追踪系统通常提供可视化界面,用于展示请求的传播路径、各个组件的处理情况以及请求的性能指标。这有助于开发人员快速定位和解决性能问题。
通过全链路追踪技术,开发人员可以更好地理解分布式系统中请求的处理过程,及时发现并解决性能问题,提高系统的稳定性和性能。
redis内存优化
09
Redis 是一种基于内存的键值存储数据库,因此内存优化对于 Redis 的性能和成本效益至关重要。以下是一些 Redis 内存优化的建议:
压缩数据:对于存储的数据,尤其是值(value),考虑使用压缩算法来减少内存占用。例如,可以使用 Redis 的压缩列表(ziplist)来存储小型哈希表或列表,或者使用外部压缩工具如 Snappy 或 LZ4 来对数据进行压缩。
选择合适的数据结构:根据实际需求选择最适合的数据结构,以减少内存占用。例如,使用哈希表存储具有相似字段的对象,而不是将它们存储为单独的键值对。
合并小键值对:避免存储大量小键值对,而是将它们合并成较大的数据结构。这样可以减少 Redis 存储的元数据开销,并降低内存使用率。
设置合适的过期时间:对于不再需要的数据,及时设置过期时间,使其在一定时间后自动从内存中删除,释放内存空间。
使用内存淘汰策略:根据业务需求选择合适的内存淘汰策略(eviction policy),例如 LRU(最近最少使用)、LFU(最少使用频率)等,以确保内存中存储的是最有价值的数据。
分片存储:将数据分片存储到多个 Redis 实例中,以减少单个实例的内存占用。可以使用 Redis Cluster 或者客户端库提供的分片功能来实现数据的分片存储。
监控内存使用情况:定期监控 Redis 实例的内存使用情况,及时发现并解决内存占用过高的问题。可以使用 Redis 的监控命令或者第三方监控工具来实现。
升级硬件配置:如果可能的话,考虑升级服务器的内存配置,以提高 Redis 实例的内存容量,从而满足业务需求。
通过以上优化措施,可以有效地减少 Redis 实例的内存占用,提高系统的性能和稳定性,同时降低成本。
tcp与udp
10
TCP(Transmission Control Protocol)和UDP(User Datagram Protocol)是两种常用的传输层协议,它们在网络通信中扮演着不同的角色,适用于不同的应用场景。
TCP(传输控制协议):
面向连接:TCP 是一种面向连接的协议,它在通信之前需要建立连接,然后进行数据传输,最后释放连接。
可靠性:TCP 提供可靠的数据传输,通过序号、确认和重传机制确保数据的完整性和顺序性。
流量控制:TCP 使用滑动窗口机制进行流量控制,确保发送方不会发送过多的数据导致接收方无法处理。
拥塞控制:TCP 使用拥塞避免和拥塞控制算法来避免网络拥塞,并在网络拥塞发生时降低发送速率。
适用场景:对于需要可靠传输、数据完整性和顺序性较为重要的应用场景,如网页浏览、文件传输、电子邮件等,通常选择 TCP。
UDP(用户数据报协议):
无连接:UDP 是一种无连接的协议,通信双方之间不需要建立连接,可以直接发送数据报。
不可靠性:UDP 不保证数据传输的可靠性,数据报可能丢失、重复或者顺序错乱。
无流量控制:UDP 不提供流量控制和拥塞控制,发送方可以按照自己的速率发送数据。
低延迟:由于不需要建立连接和提供可靠性保证,UDP 的延迟较低,适用于对实时性要求较高的应用场景。
适用场景:对于实时性要求较高、允许一定数据丢失或顺序错乱的应用场景,如实时音视频传输、在线游戏等,通常选择 UDP。
总的来说,TCP 提供可靠的、有序的、面向连接的数据传输,适用于对数据完整性和顺序性要求较高的应用场景;而 UDP 提供低延迟的、无连接的、不可靠的数据传输,适用于对实时性要求较高、允许一定数据丢失或顺序错乱的应用场景。在实际应用中,根据具体的需求和场景选择合适的协议进行通信。
php脚本编译执行原理
11
PHP 脚本的执行可以分为编译和运行两个阶段,下面是 PHP 脚本编译执行的基本原理:
编译阶段:
词法分析(Lexical Analysis):PHP 解释器首先将 PHP 脚本文件中的字符流转换为 token 流,这一过程称为词法分析。在此阶段,PHP 解释器识别出脚本中的各种关键字、标识符、操作符等,并生成相应的 token。
语法分析(Syntax Analysis):在词法分析完成后,PHP 解释器将 token 流转换为语法树(Syntax Tree),这一过程称为语法分析。语法分析的目的是检查脚本中的语法结构是否合法,并生成对应的语法树。
编译优化(Compilation Optimization):一些 PHP 编译器可能会对生成的语法树进行优化,以提高执行效率。这包括常见的优化技术,如常量折叠、函数内联、代码块删除等。
运行阶段:
解释执行(Interpretation):PHP 脚本的运行是通过解释器来实现的。解释器按照语法树的结构逐行解释执行 PHP 脚本,执行每条语句所对应的操作,并将结果输出到浏览器或其他输出设备。
动态类型解析(Dynamic Type Resolution):PHP 是一种动态类型语言,变量的类型可以在运行时动态确定。因此,在执行过程中,解释器需要对变量类型进行动态解析,以确定适当的操作。
函数调用和异常处理(Function Invocation and Exception Handling):当 PHP 脚本中调用函数或方法时,解释器会根据函数的定义执行相应的操作。同时,解释器还会监视脚本的执行过程,捕获并处理可能出现的异常情况。
总的来说,PHP 脚本的编译执行过程包括词法分析、语法分析、编译优化和解释执行等阶段。编译阶段将脚本文件转换为可执行的中间表示形式,而运行阶段则负责实际执行脚本并生成最终结果。
fpm与nginx工作机制
12
PHP-FPM(FastCGI Process Manager)和Nginx 是一种常见的组合,用于运行 PHP 网站和应用程序。它们之间的工作机制如下:
Nginx:
Web 服务器:Nginx 是一个高性能的 Web 服务器,常用于静态内容服务、反向代理和负载均衡。
反向代理:Nginx 可以作为反向代理,接收客户端请求并将其转发到后端的 PHP 处理器(如 PHP-FPM)。
静态文件服务:Nginx 可以直接提供静态文件(如 HTML、CSS、JavaScript 等)的服务,而无需将请求发送到 PHP 处理器。
PHP-FPM:
PHP 解释器管理器:PHP-FPM 是一个 PHP FastCGI 进程管理器,负责管理 PHP 解释器的运行。
连接管理:PHP-FPM 负责接收来自 Nginx 的请求,并将其分配给 PHP 解释器处理。它可以管理多个 PHP 进程池,每个进程池都可以配置独立的参数,如最小和最大进程数、空闲进程超时时间等。
进程管理:PHP-FPM 负责启动、停止和管理 PHP 进程。它可以根据负载情况动态调整 PHP 进程池中的进程数量,以提供更好的性能和资源利用率。
工作流程如下:
客户端请求:客户端发送 HTTP 请求到 Nginx。
Nginx 处理:Nginx 接收到请求后,根据配置进行处理:
如果请求是静态文件,Nginx 直接返回文件内容。
如果请求需要 PHP 处理,Nginx 将请求转发给 PHP-FPM。
PHP-FPM 处理:PHP-FPM 接收到请求后,根据配置的进程池管理方式(如动态、静态、按需等),将请求分配给 PHP 进程处理。
PHP 进程处理:PHP 进程执行请求所对应的 PHP 脚本,生成响应并返回给 PHP-FPM。
PHP-FPM 返回:PHP-FPM 将 PHP 进程生成的响应返回给 Nginx。
Nginx 返回:Nginx 将 PHP-FPM 返回的响应返回给客户端。
通过这种方式,Nginx 负责处理静态内容和反向代理,而 PHP-FPM 则负责处理动态 PHP 内容,二者配合工作以提供高性能和稳定性的 Web 服务。
git cherry-pick
13
git cherry-pick 是一个用于将单个提交从一个分支应用到另一个分支的 Git 命令。它的作用是选择某一个分支的某一个提交,将其复制到当前分支,并创建一个新的提交记录,而不影响其他提交。
基本用法如下:
git cherry-pick <commit-hash>
其中 <commit-hash> 是要应用的提交的哈希值。
使用步骤:
1、切换到目标分支:首先,你需要切换到你想要应用变更的目标分支。
git checkout <target-branch>
2、Cherry-pick 提交:运行 git cherry-pick 命令,指定你想要应用的提交的哈希值。
git cherry-pick <commit-hash>
3、解决冲突(如果有):如果在 cherry-pick 过程中出现冲突,你需要手动解决冲突,并完成提交。
4、提交变更:如果没有冲突,Git 将自动创建一个新的提交,包含被 cherry-pick 的变更。
注意事项:
如果被 cherry-pick 的提交已经存在于目标分支中,则 cherry-pick 操作会被忽略,不会创建新的提交。
Cherry-pick 的提交只是复制了提交内容,并创建了一个新的提交记录,但不会影响原始提交所在的分支或其他分支的历史记录。
Cherry-pick 操作可能会导致提交的 SHA-1 值发生变化,因为它们会生成一个新的提交对象。
git cherry-pick 是一个非常有用的命令,特别是在需要将某些特定的变更应用到其他分支时,但又不想合并整个分支的情况下。
session共享
14
在 PHP 中,会话(Session)共享是指在多个页面或应用程序之间共享会话数据的能力。通常情况下,每个用户与服务器建立一个会话,并且该会话在用户与服务器之间保持活动状态,直到用户关闭浏览器或会话超时。在 PHP 中,可以通过以下几种方式实现会话共享:
使用共享存储:
将会话数据存储在一个共享的地方,例如数据库或缓存服务器(如 Redis)中。
当用户在一个应用程序中开始会话时,将会话数据存储在共享存储中。
其他应用程序可以访问相同的共享存储,并获取或修改相同的会话数据。
使用跨域 Cookie:
如果多个应用程序位于同一域名下,可以通过设置 Cookie 的域名参数为该顶级域名来实现会话共享。
这样,一个应用程序设置的 Cookie 可以被其他应用程序访问和使用,从而实现会话共享。
手动传递会话标识符:
在链接或表单中,将当前会话的标识符作为参数传递给其他应用程序。
其他应用程序在接收到会话标识符后,可以使用该标识符来获取或修改会话数据。
使用单点登录(Single Sign-On,SSO):
单点登录是一种身份验证机制,允许用户通过一次登录获得对多个应用程序的访问权限。
一旦用户登录到其中一个应用程序,其他应用程序会通过共享会话或令牌来验证用户的身份,从而实现会话共享。
时间复杂度
15
时间复杂度是衡量算法执行时间随输入规模增长而变化的度量。它用来估计算法运行时间的增长速度,通常以大 O 表示。在分析算法时间复杂度时,我们关注的是算法对输入规模 n 的增长而言所需的操作次数。
以下是一些常见的时间复杂度及其代表的算法效率级别:
O(1) - 常数时间复杂度
O(log n) - 对数时间复杂度
O(n) - 线性时间复杂度
O(n log n) - 线性对数时间复杂度
O(n^2) - 平方时间复杂度
O(n^k) - 多项式时间复杂度(k 为常数)O(2^n) - 指数时间复杂度
O(n!) - 阶乘时间复杂度
在选择算法时,要尽量优先考虑时间复杂度较低的算法,以确保对于大规模数据集也能够在合理的时间内完成计算。
网站过程解析
16
网站过程解析通常指的是对一个网站的运作过程进行详细的分析和描述。这种解析可以包括从用户访问网站到服务器处理请求再到最终呈现页面给用户的整个过程。以下是对网站过程解析的一般步骤:
1、用户访问:
用户在浏览器中输入网站地址或点击链接来访问网站。
浏览器向服务器发送 HTTP 请求。
2、DNS 解析:
如果用户输入了网站域名,浏览器会将其发送到 DNS 服务器进行解析,以获取该域名对应的 IP 地址。
DNS 解析器将域名解析为相应的 IP 地址,使浏览器能够向正确的服务器发送请求。
3、服务器处理请求:
一旦浏览器获得了服务器的 IP 地址,它会向该服务器发送 HTTP 请求。
服务器接收到请求后,根据请求的 URL、参数等信息,调用相应的处理程序。
4、后端处理:
在服务器端,后端处理程序(如 PHP、Python、Node.js 等)会处理请求,可能包括从数据库中检索数据、执行业务逻辑等。
处理程序生成要返回给客户端的 HTML、CSS、JavaScript 等内容。
5、数据获取与处理:
如果网页需要从数据库中获取数据,服务器端会执行相应的数据库查询操作,并将结果返回给处理程序。
处理程序可能会对获取的数据进行处理,如格式化、过滤等。
6、页面生成:
服务器端处理程序将获取到的数据与 HTML 模板、CSS、JavaScript 等结合,生成完整的网页内容。
7、响应返回:
服务器将生成的网页内容作为 HTTP 响应返回给用户的浏览器。
8、页面渲染:
浏览器接收到服务器返回的响应后,开始解析 HTML、CSS,并执行 JavaScript。
浏览器根据解析得到的信息渲染页面,包括布局、样式、交互等。
9、页面呈现:
最终,浏览器将渲染好的页面呈现给用户,用户可以看到网站的内容并与之交互。
这些步骤可能在实际应用中会有所变化,具体取决于网站的架构、技术栈以及所使用的服务器和客户端软件。
数据结构说明
17
在 PHP 中,有多种数据结构可用于组织和存储数据。以下是其中一些常见的数据结构:
数组(Array):
数组是一种有序的、键值对的集合数据结构。
在 PHP 中,数组可以包含任意类型的数据,可以通过数字索引或字符串键访问元素。
数组可以是索引数组(使用数字索引)、关联数组(使用字符串键)或混合数组。
// 索引数组
$indexArray = array("apple", "banana", "orange");
// 关联数组
$assocArray = array("name" => "John", "age" => 30);
// 混合数组
$mixedArray = array("apple", "name" => "John", 3 => "orange");
列表(List):
在 PHP 中,列表通常是指使用数组实现的有序集合。
可以使用数组函数(如 array_push() 和 array_pop())在数组的末尾添加或删除元素,模拟栈和队列的行为。
$list = array("apple", "banana", "orange");
array_push($list, "grape"); // 添加元素
$lastElement = array_pop($list); // 删除末尾元素
栈(Stack):
栈是一种后进先出(LIFO)的数据结构,在 PHP 中可以使用数组实现。
使用 array_push() 和 array_pop() 函数来模拟栈的压入和弹出操作。
$stack = array();
array_push($stack, "apple"); // 压入元素
array_push($stack, "banana");
$topElement = array_pop($stack); // 弹出元素
队列(Queue):
队列是一种先进先出(FIFO)的数据结构,在 PHP 中可以使用数组实现。
使用 array_push() 和 array_shift() 函数来模拟队列的入队和出队操作。
$queue = array();
array_push($queue, "apple"); // 入队
array_push($queue, "banana");
$firstElement = array_shift($queue); // 出队
堆(Heap):
在 PHP 中,堆通常使用 SplHeap 类或 SplMinHeap/SplMaxHeap 类实现。
SplHeap 是一个抽象类,SplMinHeap 和 SplMaxHeap 是其子类,分别代表最小堆和最大堆。
$minHeap = new SplMinHeap();
$minHeap->insert(4);
$minHeap->insert(2);
$minHeap->insert(5);
$minValue = $minHeap->extract(); // 从最小堆中提取最小值
链表(Linked List):
PHP 中没有内置的链表数据结构,但可以通过自定义类来实现链表。
链表由节点组成,每个节点包含数据和指向下一个节点的指针。
class Node {
public $data;
public $next;
public function __construct($data) {
$this->data = $data;
$this->next = null;
}
}
哈希表(Hash Table):
在 PHP 中,哈希表通常是通过关联数组(数组实现的有序映射)来实现的。
使用字符串键来查找、插入和删除元素,哈希表具有快速的查找性能。
$hashTable = array("name" => "John", "age" => 30);
echo $hashTable["name"]; // 输出 John
集合(Set):
PHP 中没有内置的集合数据结构,但可以使用数组来实现集合。
集合是一种无序且不包含重复元素的数据结构。
$set = array("apple", "banana", "orange");
$set[] = "apple"; // 重复元素将不会被添加
分割线
为了让各位方便:交流、交友、技术视频、资源分享、接私活 等等,可以扫下面二维码(wx:xzzs730),备注 “ 技术 ” 就可以通过审核。
进群的小伙伴请加右侧私人微信(备注:技术)
-----商务合作分隔线----
商务合作,关注公众号回复“商务合作”