【PHP常见面试笔记(一)】

1.Redis主从配置怎么实现?在哪些功能中应用到?

Redis主从配置是实现Redis高可用性的重要手段之一,它可以将主节点数据复制到从节点,实现数据备份和容灾。具体实现方法为:
  1. 在主节点上配置redis.conf文件,设置slaveof从节点的IP地址和端口号。

  1. 在从节点上配置redis.conf文件,设置为从节点,并设置master的IP地址和端口号。

  1. 启动主节点和从节点,通过命令行或者配置文件检查主从节点的连接状态。

Redis主从配置可以应用于以下场景:
  1. 高可用性:主从配置可以实现Redis的高可用性,当主节点不可用时,从节点可以顶替主节点继续服务,保证业务的连续性。

  1. 容灾备份:主从配置可以将主节点的数据备份到从节点,当主节点数据丢失或损坏时,可以通过从节点数据的恢复来实现容灾备份功能。

  1. 负载均衡:主从配置可以实现负载均衡的功能,当主节点的并发请求较大时,可以将请求分发到从节点上进行处理,提高系统的处理能力和吞吐量。

综上所述,Redis主从配置是一项非常重要的功能,可以提高Redis的容灾性、可用性和扩展性。

2.Git怎么将项目初始化?怎么使用?

第一部分:将项目初始化

在Git中,需要将项目初始化并创建一个仓库,才能进行版本控制。在Git Bash终端中进入项目所在目录,执行以下命令初始化项目:

git init

执行成功后,Git会在当前目录下创建一个.git目录,用于存放版本库的相关文件。

第二部分:Git的使用

Git是一款非常强大的版本控制工具,它可以帮助我们更好地管理和追踪代码的变化。以下是一些常用的Git命令:

  1. git add:将文件添加到缓存区。
git add file.txt
  1. git commit:将文件提交到本地仓库。
git commit -m "commit message"
  1. git push:将本地仓库中的修改推送到远程仓库。
git push origin master
  1. git pull:从远程仓库中拉取最新的代码。
git pull origin master
  1. git clone:从远程仓库中复制一个完整的项目到本地。
git clone https://github.com/user/project.git
  1. git branch:查看本地分支。
git branch
  1. git checkout:切换分支。
git checkout dev
  1. git merge:合并分支。
git merge dev

以上是一些常用的Git命令,学会这些命令可以帮助我们更好地使用Git进行版本控制。

3.mysql主从的配置方式?慢查询日志的作用是什么?

第一部分:MySQL主从的配置方式

MySQL主从配置是实现MySQL高可用性和负载均衡的重要手段之一,它可以将主节点上的数据同步到从节点上,实现数据备份和容灾。具体实现方法为:

  1. 在主节点上执行以下命令,创建一个新用户,并授权给从节点的IP地址:
CREATE USER 'repl'@'slave_ip' IDENTIFIED BY 'password';
GRANT replication slave ON *.* TO 'repl'@'slave_ip';
  1. 在主节点修改my.cnf配置文件,开启二进制日志,并设置server-id参数:
[mysqld]
log-bin=mysql-bin 
server-id=1 
  1. 在从节点上修改my.cnf配置文件,设置server-id参数,并设置为从节点:
[mysqld]
server-id=2
  1. 在从节点上执行以下命令,将主节点数据同步到从节点,并设置从节点连接主节点的用户名、密码、IP地址和端口号:
CHANGE MASTER TO
MASTER_HOST='master_ip',
MASTER_USER='repl',
MASTER_PASSWORD='password',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=107;
  1. 在从节点上启动从节点服务,执行以下命令开始同步主节点数据:
START SLAVE;
第二部分:慢查询日志的作用

慢查询日志是MySQL提供的一种记录查询速度较慢的日志,记录了那些执行时间超过特定时间的SQL查询语句,它的作用是帮助DBA或者开发人员找出哪些查询耗费了过多的时间,从而优化数据库性能。

慢查询日志的作用有以下几个方面:
  1. 优化数据库性能:通过慢查询日志可以快速定位哪些SQL查询语句执行时间较慢,可以对这些查询进行优化,提高数据库性能。

  1. 发现程序问题:通过慢查询日志可以发现一些程序问题,例如卡死、死锁等问题,从而可以快速定位这些问题并解决。

  1. 安全审计:通过慢查询日志可以发现一些异常查询,例如敏感数据查询、恶意查询等,提供了安全审计的能力。

综上所述,慢查询日志是MySQL提供的非常实用的工具,它可以帮助我们发现数据库性能问题、程序问题和安全问题,从而更好地管理和维护MySQL数据库。

4.怎么进行防注入攻击?

防注入攻击主要是指SQL注入攻击,即黑客通过构造恶意的SQL语句,利用程序漏洞直接进入数据库,产生危害。

下面介绍几个防范SQL注入的措施:
  1. 使用预处理语句:预处理语句是一个模板,其中占位符代表变化的参数值,通过将语句和参数分开处理,从而防止黑客通过SQL注入攻击修改语句。

  1. 过滤数据输入:在输入数据时,对数据进行过滤判断,判断是否符合输入要求,例如对数字类型、日期类型、字符串类型等进行验证。

  1. 对特殊字符进行转义:在输入和输出数据时,要对特殊字符进行转义,例如单引号、双引号、反斜杠等。

  1. 数据库权限控制:合理分配数据库用户权限,将需要访问的数据和操作权限都控制在程序开发者和系统管理员手中。

  1. 安全审核代码:对系统或应用进行代码安全审核,发现存在漏洞或可被攻击的代码进行优化和改进。

以上是几个防范SQL注入攻击的措施,通过这些措施可以避免SQL注入攻击对数据库的危害,保障系统的安全性。

5.回收站功能怎么实现?软删除怎么实现?

第一部分:回收站功能的实现
回收站功能可以让用户不小心删除文件后,还有机会恢复它们。下面介绍一个简单的实现方法:
  1. 在表中添加一个is_deleted字段,用于标记数据是否被删除。

  1. 当用户删除数据时,将对应数据的is_deleted字段置为1,而不是直接删除数据。

  1. 实现回收站页面,页面中只显示is_deleted字段为1的数据,显示已经被删除的数据。

  1. 在回收站页面提供还原和永久删除的操作,通过更新is_deleted字段实现数据的恢复或删除。

第二部分:软删除的实现
软删除是指在数据库中不是直接删除记录,而是通过在表中添加一个标志位来标记该记录是否被删除。下面介绍软删除的实现方法:
  1. 在表中添加一个is_deleted字段,用于标记记录是否被删除。

  1. 在查询数据时,只查询is_deleted字段为0的数据,即没有被删除的记录。

  1. 当需要删除数据时,直接更新is_deleted字段为1,而不是删除数据。

  1. 当需要恢复数据时,根据需要恢复的数据ID,更新对应记录的is_deleted字段为0,即将记录标记为未被删除。

通过软删除的实现,可以将被删除的记录标记为已删除,但并不直接删除记录,从而保留数据完整性,并可以有机会进行数据恢复。同时,在查询数据时,只查询is_deleted字段为0的数据,也可以有效地维护数据的安全性。

6.Redis消息队列怎么使用?

Redis消息队列是一种使用Redis实现的轻量级消息队列,它可以很方便地实现异步任务处理、事件驱动等功能。

下面介绍Redis消息队列的使用方法:
  1. 安装redis-py库:
pip install redis
  1. 连接Redis服务器:
import redis

r = redis.StrictRedis(host='localhost', port=6379, db=0)
  1. 消息生产者向队列中添加消息:
r.lpush('queue_name', 'message')
  1. 消费者从队列中获取消息进行处理:
message = r.brpop('queue_name', timeout=0)
  1. 消费者对获取到的消息进行处理,并从队列中取下一条消息:
while True:
    message = r.brpop('queue_name', timeout=0)
    process_message(message[1])
  1. 在处理消息时,需要遵循“处理异常就删除”的原则,即在处理消息时出现异常要将消息从队列中删除,避免出现重复处理或造成消费者堆积的情况。
  1. 如果需要支持多个消费者同时处理消息,可以使用Redis消息通知机制,即使用subscribe方法订阅发布/订阅通道,让多个消费者同时监听队列。

以上是Redis消息队列的使用方法,通过使用Redis消息队列可以实现同步任务异步处理,提高系统的处理效率和响应速度,同时还可以保障系统的可靠性和稳定性。

7.后台的客服功能怎么使用?

后台的客服功能通常是基于实时聊天的方式,实现客服人员和用户的沟通和交流。

下面介绍客服功能的实现方法:
  1. 安装即时通讯SDK或者使用流行的即时通讯云服务(例如阿里云即时通讯IM、融云等),并在后台集成SDK或云服务的API,实现即时通讯的功能。

  1. 用户进入前台页面时,可以通过浮窗或侧边栏等方式展示在线客服入口,用户点击入口即可发起咨询。

  1. 当用户发起咨询时,在后台自动分配一个客服人员,客服人员收到用户咨询后,可以通过即时通讯的方式进行沟通和交流。

  1. 在聊天过程中,客服人员可以在后台管理界面查看用户的相关信息,例如咨询内容、用户名、所在地区等,方便客服人员更好地为用户提供服务。

  1. 当用户的咨询结束后,客服人员可以将聊天记录存档并评价用户的评价。

需要注意的是,客服人员需要及时回复用户的咨询,为用户提供良好的服务体验。因此,建议在后台开启咨询自动分配功能,实现客服人员的快速配合和服务响应。同时,客服人员需要对聊天记录进行保密,避免用户的信息被泄露。

8. 云存储的使用流程。

云存储是指将文件或数据存储在云端服务商提供的存储空间中,用户可以通过API或者Web界面进行访问和管理。

下面介绍云存储的使用流程:
  1. 注册一个云存储服务商的账号,例如阿里云OSS、腾讯云COS、AWS S3等。

  1. 创建一个存储桶(Bucket),所谓Bucket,就是存放对象的容器,桶名需要全局唯一,会作为访问的主机名一部分,并指定存储地域。

  1. 上传需要存储的文件(对象)到存储桶中,可以使用API调用,也可以通过云服务商提供的Web界面进行管理。

  1. 访问存储桶中的文件,可以使用API调用或者直接通过浏览器访问对象的URL地址。

  1. 对存储桶中的文件进行管理,例如文件的删除、复制、移动等操作,可以使用API调用或云服务商提供的Web界面进行管理。

需要注意的是,云存储服务商通常基于容量、流量、QPS等指标来计费,因此需要根据实际需求选择适合自己业务的存储方案。同时,在使用云存储时,需要注意数据的安全性,建议对重要数据进行加密和备份。

9.数据库表结构怎么防止重名情况?模型层怎么建立对应关系?

防止重名情况可以采用以下两种方法:
  1. 对于可能出现重名情况的表属性,可以加上唯一索引或唯一约束,避免重名的情况。例如对于用户表中的用户名可以加一个唯一索引,这样新增和修改时如果有重名的情况就会报错,需要进行处理。

  1. 在数据存储前对名称进行处理,添加序列号或者时间戳避免重名重复出现。

对于模型层的对应关系建立,通常采用ORM框架实现。

ORM框架是指对象关系映射,将应用程序中的对象和数据库表之间建立映射关系,在操作对象时自动操作数据库表,省去了手写SQL的代码。常用的ORM框架包括Django的ORM、SQLAlchemy等。

通过ORM框架可以建立对象和数据库表的映射关系,提供ORM映射中的增删改查操作,以对象的形式进行数据库操作,代码编写效率和可读性都得到了极大的提高。对于建立对应关系,只需要在ORM映射中指定相应的关系,例如对于一对多的关系,需要在ORM中指定外键等关联信息。在操作数据时只需要操作对象,ORM框架会自动将数据保存到相应的表中。

10.订单表怎么建立副表?垂直拆表的策略是什么?

订单表使用副表(也称拓展表)通常是存储与订单相关的具体信息,例如订单商品列表、物流信息等。副表和主表之间通过外键进行关联,可以实现数据的强关联和查询性能的优化。

下面介绍建立订单副表的方法:
  1. 确定副表和主表的关系和属性,副表中的属性通常与主表相关。

  1. 在副表中添加外键,指向主表中的关联字段。

  1. 创建对应的ORM映射关系,通过ORM操作时,自动处理副表和主表之间的数据关联。

垂直拆表是一种常用的数据库拆分策略,是将一个大表按照业务相关性将不同的属性拆分成不同表,避免表中的数据字段冗余和查询效率低下。在订单表中,我们可以根据业务逻辑将不同的属性进行分离,例如将订单的基本信息和订单的操作日志、物流信息、商品信息等分开存储。

垂直拆表的策略有以下几种:
  1. 按照业务拆分:将数据库表按照业务属性和业务负责人进行分类拆分。

  1. 按照热点数据拆分:将常用的数据分为一组,不常用的数据分为另一组,在存储时对热点数据进行优化。

  1. 按照数据安全垂直切割:将不同的数据放在不同的数据库中,提高数据的安全性。

需要注意的是,垂直拆表适用于表中属性之间关联性不高的情况,如果属性之间相互依赖,拆分后可能会增加复杂度和查询开销。因此,需要仔细考虑业务需求和数据存储方式,做出合理的拆分策略。

11.varchar和char的区别是什么?tinyint/smallint/int的区别?

varchar和char的区别:
  1. 存储方式不同:char是固定长度的,如果存储的内容不够指定长度,会在末尾增加空格进行填充,占用的存储空间是固定的。而varchar是可变长度的,会根据存储内容自动分配空间大小,不会产生额外的空白填充。

  1. 查询效率不同:char比varchar查询效率高,因为不需要像varchar一样进行长度计算和字符填充。

  1. 存储容量不同:char占用空间较大,varchar相对更省空间。

tinyint/smallint/int的区别:
  1. 存储空间不同: tinyint占用1个字节的存储空间,适用于存储0或1或者状态等只需用1个字节的情况。而smallint占用2个字节的存储空间,int占用4个字节,适用于数据较大的情况。

  1. 表示数据范围不同: tinyint只能表示-128到127之间的整数,而smallint和int可以表示更大的整数范围。

  1. 计算精度不同:tinyint只能表示整数类型,而smallint和int支持计算时的精度保留。

需要根据实际业务需求来选择适当的数据类型,对于只有0或1等简单状态情况,使用tinyint可以大大节省存储空间和查询效率。而对于数量较大和精度要求较高的数据,应该选择较大的数据类型,保证计算精度和数据范围。

12.防止重复下单的实现方式

防止重复下单可以采用以下几种方式:

  1. 前端控制:在前端页面中禁用下单按钮,直至用户提交订单的请求返回成功。在提交订单的请求中增加时间戳或随机数等标识,避免重复提交。

  1. 在数据库中增加唯一索引来实现唯一性约束:可以在订单表中增加唯一索引或者唯一约束,确保订单编号是唯一的,避免同样的订单被重复下单。

  1. Redis分布式锁:在提交订单请求前,使用Redis分布式锁,确保同一时间只有一个线程或进程处理订单提交请求,在操作完后释放锁。

  1. Token验证:可以通过验证每个下单请求中携带的Token值,避免同一个请求被多次提交,确保订单提交是唯一的。

以上方式都可以实现防止重复下单的功能,可以根据实际业务需求和系统架构选择适合的方式。在实现防止重复提交的过程中,需要考虑系统高并发下的一些问题,例如分布式环境下的数据异步一致性等。需要综合考虑,保证系统的稳定性和安全性。

13.云存储怎么调用?白名单怎么设置?图片内容怎么进行审核?

云存储调用方式:

通常来说,云存储服务提供商会提供相应的API或SDK,方便开发人员进行开发和调用。开发人员可以根据提供商的API或SDK进行开发,实现云存储文件的上传、下载、删除等功能。

白名单设置:

为了防止非授权用户恶意访问或下载云存储中的文件,可以设置白名单。在云存储服务提供商的管理控制台中,可以设置允许访问或者下载云存储的IP地址段或域名。只有在白名单中的IP地址或域名才可以进行访问或下载操作,其他IP地址或者域名将不能访问,保证云存储文件的安全性。

图片审核:

为了保证云存储中的内容不违反政策法规,通常需要进行审核。一些云存储服务提供商提供图片内容审核功能,可以进行色情、暴力、政治等内容的检测。如果检测到违规内容,可以禁止上传或者进行处理,例如进行打马赛克、加水印等操作。如果需要审核内容,可以调用提供商的API或SDK,上传需要审核的内容,收到审核结果后进行相应的处理。

总之,云存储提供了方便快捷的文件存储和管理方式,同时也需要注意文件的安全和合规性。通过设置白名单和进行内容审核,可以保证云存储的安全性和合规性。

14.Redis有哪些数据类型?能实现哪些功能?

Redis支持以下5种数据类型:
  1. 字符串类型(string):可以存储字符串、数字或者二进制数据。常用命令有set、get、incr等。

  1. 列表类型(list):可以存储有序的字符串列表。常用命令有lpush、rpop、llen等。

  1. 集合类型(set):可以存储无序且唯一的字符串列表。常用命令有sadd、srem、sismember等。

  1. 哈希类型(hash):可以存储键值对,其中键和值都是字符串类型。常用命令有hget、hset、hdel等。

  1. 有序集合类型(zset):可以存储有序且唯一的字符串列表,并对列表中每个元素进行打分。常用命令有zadd、zrange、zrank等。

Redis支持的功能包括:
  1. 缓存的存储和读取:可以将数据缓存到Redis中,从而加快数据的读取速度;

  1. 发布/订阅:Redis允许客户端订阅一个或多个频道,当频道中有消息时,客户端将自动收到消息;

  1. 事务处理:Redis提供Multi/Exec/Discard/Watch等命令来支持事务处理;

  1. 原子计数器:Redis可以对数字类型的数据进行原子加减操作;

  1. 排序:Redis具有对集合和有序集合排序的能力;

  1. 搜索:Redis可以实现基于关键字的搜索。

总之,Redis是一种高性能、支持多种数据类型的键值对存储系统,可以用于缓存、队列、发布订阅和计数器等应用场景。同时,由于其内存数据库的特点,Redis的读写速度非常快,适合高并发的应用场景。

15.Rbac的数据库表结构?怎么渲染出多对多的数据?递归循环的核心逻辑?

RBAC数据库表结构:
  1. 用户表(User):存储用户信息,与角色表多对多关系。

  1. 角色表(Role):存储角色信息,与权限表多对多关系。

  1. 权限表(Permission): 存储权限信息,可以是访问权限、操作权限等。

  1. 用户角色关系表(User_Role):存储用户与角色之间的多对多关系。

  1. 角色权限关系表(Role_Permission):存储角色与权限之间的多对多关系。

多对多数据的渲染:

通常来说,可以使用第三方库来渲染多对多数据。例如,在PHP语言中,可以使用Laravel等框架提供的Eloquent ORM来实现多对多数据渲染。在Eloquent ORM中,可以使用with方法来加载多对多关系的数据,例如:

$users = User::with('roles')->get();

在上面的示例中,使用with('roles')方法来加载用户与角色之间的多对多关系,从而可以让应用程序轻松访问用户所属的角色。

递归循环的核心逻辑:

在渲染RBAC的数据结构时,通常需要使用递归循环来处理多层级的数据。例如,在渲染菜单或者权限树时,需要遍历数中的每一个节点,找出该节点的所有子节点,然后递归渲染子节点,直到所有节点都被渲染完毕。

递归循环的核心逻辑通常包括:
  1. 递归退出条件:当节点没有子节点时,退出递归。

  1. 遍历子节点:遍历节点的子节点,并对每个子节点进行递归操作。

  1. 递归结果合并:将每个子节点渲染的结果进行合并,得出最终结果。

例如,在PHP语言中可以使用下面的代码实现递归循环:

function renderPermissionTree($permissions, $pid = 0)
{
    $arr = array();
    foreach ($permissions as $permission) {
        if ($permission->pid == $pid) {
            $children = renderPermissionTree($permissions, $permission->id);
            if ($children) {
                $permission->children = $children;
            }
            $arr[] = $permission;
        }
    }
    return $arr;
}

以上代码使用递归来遍历所有权限节点,并将所有子节点合并成一个树状结构。其中,renderPermissionTree函数的第一个参数是需要渲染的权限数据,第二个参数是当前节点的pid(默认为根节点)。在函数中,遍历权限数据,筛选出pid为当前节点的数据,对这些子节点进行递归操作,最终返回渲染完毕的权限树。

16.接口验签的实现方式?哪些接口需要用jwt中间件包裹?

接口验签通常的实现方式是:
  1. 服务端和客户端约定一个私钥和公钥,私钥只有服务端知道,公钥可以公开。

  1. 客户端在请求接口的时候,会将请求参数按照一定的规则(如按照参数名称排序)进行拼接,并使用私钥进行加密得到加密后的字符串。

  1. 客户端将加密后的字符串和公钥一同发送给服务端。

  1. 服务端在接收到请求后,获取请求参数,按照同样的规则进行拼接,并使用同样的私钥进行加密,得到一个新的加密后的字符串。

  1. 服务端将客户端传来的加密后的字符串和自己加密生成的字符串进行对比,如果相同则认为请求是合法的,否则认为请求是非法的。

通常来说,接口验签可以确保接口的安全性,避免恶意篡改接口数据。但是需要注意的是,验证签名仅仅保证请求的完整性,而不能防止重放攻击等攻击方式,还需要结合其他措施进行防御。

需要用JWT中间件包裹的接口:
JWT(JSON Web Token)是一种用于身份验证的安全传输方式,可以将用户的信息存储在JSON格式的Token中。通常来说,需要用JWT中间件包装的接口包括:
  1. 需要进行身份验证的接口,例如用户登录、获取用户信息等。

  1. 需要访问权限控制的接口,例如修改个人信息、发布文章等。

  1. 需要其他安全保护的接口,例如支付、密码修改等。

使用JWT中间件包裹接口可以确保接口的安全性,只有通过身份验证和访问权限控制的用户才能访问这些接口,保证了接口的正确性和可靠性。

17.tp6的事务怎么使用?数据库引擎用哪种?

使用TP6的事务:
TP6提供了非常方便的事务处理方法,可以使用Db类的transaction、commit和rollback方法分别开启事务、提交事务和回滚事务。具体操作步骤如下:
  1. 开启事务:使用Db类的transaction方法,该方法接受一个回调函数作为参数,回调函数中的所有操作将会自动开启事务。

  1. 提交事务:使用Db类的commit方法,该方法将会提交事务。

  1. 回滚事务:使用Db类的rollback方法,该方法将会撤销之前的事务操作。

例如,在TP6中使用事务可以这样实现:

use think\facade\Db;

Db::transaction(function () {
    // 业务逻辑处理
    // ...
    // 提交事务
    Db::commit();
}, function () {
   // 事务回滚
   Db::rollback();
});

在上述示例中,使用Db类的transaction方法开启事务,并且在第一个回调函数中进行业务逻辑的处理;在业务逻辑处理完成后,使用Db类的commit方法提交事务;如果在业务逻辑处理过程中发生错误,使用第二个回调函数进行回滚操作。

数据库引擎的选择:

TP6支持多种数据库引擎,包括MySQL、PostgreSQL、SQLite等。在TP6中,可以在配置文件中指定所使用的数据库引擎,例如:

// MySQL数据库配置
return [
    // 数据库类型
    'type' => 'mysql',
    // 服务器地址
    'hostname' => '127.0.0.1',
    // 数据库名
    'database' => 'test',
    // 数据库用户名
    'username' => 'root',
    // 数据库密码
    'password' => 'password',
    // 数据库编码默认采用utf8mb4
    'charset' => 'utf8mb4',
    // 数据库表前缀
    'prefix' => '',
];

其中,type字段指定了数据库引擎的类型,hostname指定了数据库服务器的地址,database指定了所使用的数据库名称等。根据应用的实际需求,选择适合的数据库引擎可以保证系统的正常运行和高性能的表现。

18.脏读和幻读是什么意思?

脏读和幻读是数据库中两个非常重要的概念,它们都是指在并发操作中可能出现的问题。

脏读:指的是一个事务读取了另一个事务未提交的数据。比如,事务A修改了一条数据,但是还没有提交,此时事务B读取了这条数据,就出现了脏读。
幻读:指的是一个事务读取了另一个事务新增的数据,导致前后读取的数据数量不一致。比如,事务A在读取一张表中的数据时,事务B插入了一条数据,此时事务A再次读取该表中的数据时,就发现前后两次查询返回的数据数量不一致,就出现了幻读。

脏读和幻读的根本原因是并发事务之间的读写顺序不当或者没有合适的锁机制,导致一个事务读取了另一个事务未提交或新增的数据。

为了避免这些并发问题,在实际应用中可以采用如下解决方案:
  1. 在事务中使用锁机制,避免并发事务同时读写同一个数据。

  1. 通过调整事务的隔离级别,避免数据读取和写入时出现冲突,常见的隔离级别包括:读未提交、读已提交、可重复读和串行化。

  1. 对于并发访问量大的应用,可以通过分库分表或者其他一些优化手段,将读写操作分散到多个数据库或者多个表中,避免数据冲突和竞争。

总之,脏读和幻读是数据库中常见的并发问题,必须避免才能确保数据的正确性和一致性。

19.秒杀的数据库表结构怎么建立?

秒杀活动需要建立多张数据库表,并且需要根据具体的业务场景和需求来设计表结构。

下面列出了一些常用的秒杀活动表:

  1. 商品表:存储商品的相关信息,如商品ID、名称、价格、库存等。

  1. 秒杀活动表:存储秒杀活动的相关信息,如秒杀活动ID、开始时间、结束时间等。

  1. 秒杀商品表:存储秒杀商品的相关信息,如秒杀商品ID、秒杀活动ID、限购数量等。

  1. 订单表:存储用户购买商品的订单信息,如订单ID、用户ID、商品ID、购买数量等。

以下是一个简单的秒杀库存表结构示例:

  1. 商品表

字段名

类型

是否主键

描述

id

int(11)

商品 ID

name

varchar(255)

商品名称

price

decimal(10,2)

商品价格

inventory

int(11)

商品库存数量

  1. 秒杀活动表

字段名

类型

是否主键

描述

id

int(11)

秒杀活动 ID

name

varchar(255)

秒杀活动名称

start_time

datetime

秒杀开始时间

end_time

datetime

秒杀结束时间

  1. 秒杀商品表

字段名

类型

是否主键

描述

id

int(11)

秒杀商品 ID

goods_id

int(11)

商品 ID

seckill_id

int(11)

秒杀活动 ID

seckill_price

decimal(10,2)

秒杀商品价格

  1. 订单表

字段名

类型

是否主键

描述

id

int(11)

订单 ID

user_id

int(11)

用户 ID

goods_id

int(11)

商品 ID

seckill_id

int(11)

秒杀活动ID

quantity

int(11)

购买数量

pay_time

datetime

支付时间

以上仅为基本库存表结构示例,根据实际业务场景需求,可能会有不同变化,需要根据实际情况进行调整和优化设计。

20.git代码冲突怎么解决?

当多人同时在同一个 Git 分支上进行修改时,就有可能会产生代码冲突。

以下是解决 Git 代码冲突的步骤:
  1. Git pull 获取最新代码:在本地仓库中,先执行git pull命令,以获取最新的代码。此时,Git 会自动尝试合并已有的分支和下载的代码。
  1. 查看代码冲突:执行git status命令可以检查出代码冲突的文件。
  1. 手动解决代码冲突:手动修改冲突文件,将代码中产生冲突的部分进行合并、调整或者删除。
  1. 添加文件到暂存区:当代码冲突解决后,使用 git add 命令将修改后的文件添加到暂存区域。
  1. 提交代码:执行git commit命令来提交代码并添加提交信息。
  1. 推送代码:当本地分手更新完毕并通过本地测试后,执行git push命令将代码推送到远程 Git 仓库。

如果多个人对同一份代码产生了冲突,那么可以在协调员的指导下,通过团队协作来解决冲突。例如,可以在团队内部进行代码审查、讨论和协商,以确定最佳解决方案。在解决冲突时,应该注重沟通和合作,以确保代码质量和团队的协作效率。

21.mysql主从怎么实现数据同步 ?

MySQL 主从复制是一种典型的数据复制机制,可以将一个 MySQL 数据库的数据复制到另外一个 MySQL 数据库上,从而实现主数据库和从数据库之间的数据同步。

以下是 MySQL 主从实现数据同步的步骤:
  1. 配置主服务器:进入主服务器,修改my.cnf文件以启用二进制日志,并在 MySQL 控制台中创建一个备份用户。同时,还需要在控制台中运行 show master status 命令,来查看主服务器的当前 binlog 文件名和位置。

  1. 配置从服务器:进入从服务器,修改my.cnf文件以启用从服务器复制,并在控制台中运行 change master to 命令,来指定主服务器的地址、备份用户的用户名和密码,以及 binlog 文件名和位置等信息。

  1. 启动 MySQL 主从复制:在从服务器上运行 start slave 命令,以启动 MySQL 主从复制,并通过 show slave status 命令来查看从服务器的同步状态和错误信息等。

  1. 测试数据同步:在主服务器上插入、更新和删除数据,并在从服务器上查看是否已经同步了数据。

需要注意的是,在进行 MySQL 主从复制时,需要确保主服务器和从服务器之间网络稳定,且时延较小,否则会降低数据同步的效率和质量。此外,还需要及时监控 MySQL 主从复制的状态和日志,以便发现和处理同步错误和异常情况。

22.项目上线怎么绑定域名?域名解析?

将项目上线并绑定域名的步骤如下:
  1. 购买域名:首先需要购买一个域名,可以通过 腾讯云、阿里云、Godaddy、Namecheap等知名服务商购买。

  1. 配置域名解析:将域名解析到自己的服务器IP地址,可以在域名管理平台进行配置。一般来说,

域名解析配置分为两步:

a. 创建主机记录:以 www 为例,将 www 记录指向自己的服务器 IP 地址,具体配置可以参考域名管理平台的帮助文档。

b. 修改 DNS 解析服务器:将域名解析设置为自己常用的 DNS 服务器,例如:阿里云 DNS、腾讯云 DNS 等。

  1. 绑定域名到服务器:如果自己的服务器需要绑定多个域名,则可以通过在自己服务器上配置 Nginx 虚拟主机来实现。

  1. 测试域名解析:在域名绑定到服务器之后,可以通过 URL 访问自己的网站,在访问时应该可以看到网站的内容。

需要注意的是,域名解析可能需要一定的时间才能生效,因此需要耐心等待。同时,还需要确保服务器环境安全可靠,并定期进行备份和维护。

23.tp6怎么实现定时任务?linux需要配合做哪些事?

在 ThinkPHP 6 中,可以通过定时任务(Scheduled Task)来实现定期执行指定的程序代码。关于 ThinkPHP 6 定时任务,具体步骤如下:
  1. 安装 Crontab:Linux 系统下主要使用的是 Crontab 工具来设置定时任务。如果系统中没有安装 Crontab,需要先通过命令 sudo apt-get install cron 进行安装。

  1. 设置环境变量:在定时任务配置中,需要指定 PHP 解释器的路径以及项目的根目录等参数,因此需要在 Crontab 中导出环境变量。可以在系统用户的根目录中的bashrc或者zshrc文件中设置,例如:

export PATH=/usr/local/php/bin:$PATH
export APP_PATH=/path/to/your/app/
  1. 配置定时任务:可以通过 Crontab Manager 工具或者手动修改 Crontab 配置文件来添加定时任务。以下是添加定时任务的命令格式:

* * * * * command
其中,每个星号对应一个时间字段,依次表示分钟、小时、日期、月份和星期,使用通配符 * 表示不限制取值范围。command 表示要执行的 PHP 程序或者 Shell 脚本等命令。
  1. 编写任务代码:在 ThinkPHP 6 中,可以通过控制器或者事件监听器等方式来实现定时任务。例如,在控制器中创建以下任务代码,来实现每分钟自动输出当前时间的功能:

namespace app\index\controller;

use think\facade\Config;
use think\facade\Log;

class Task
{
    public function test()
    {
        Log::info("Now: " . date("Y-m-d H:i:s"));
    }
}
  1. 启用定时任务:将编写好的任务代码添加到定时任务配置中,并启用 Crontab 服务,即可自动执行定时任务。

需要注意的是,在进行定时任务配置时,需要谨慎选择执行时间和次数等参数,以免对系统运行和性能造成负面影响。同时,还需要对定期执行的任务进行监控和日志记录等处理,以便及时发现和处理问题。

24.数组怎么分割成字符串?截取字符串用什么函数?

将一个数组分割成字符串可以通过 implode 函数来实现,该函数将数组元素组合成一个字符串,可以根据自己的需求指定分割符。

例如,下面的代码将一个数组以逗号(,)为分割符组合成一个字符串:

$arr = ['apple', 'banana', 'orange'];
$str = implode(',', $arr); // apple,banana,orange
在 PHP 中,截取字符串可以使用 substr 函数。该函数需要传入三个参数:要截取的字符串、起始位置和截取长度。

例如,下面的代码将一个字符串从第二个字符开始,截取长度为五的子串:

$str = 'abcdefg';
$sub = substr($str, 1, 5); // bcdef
需要注意的是,如果要从字符串的末尾开始截取,可以为起始位置传入负数。

例如,下面的代码将一个字符串从倒数第二个字符开始,截取长度为三的子串:

$str = 'abcdefg';
$sub = substr($str, -2, 3); // fg

另外,还可以使用 mb_substr 函数来对多字节字符进行截取,该函数和 substr 的使用方式基本相同,只是可以对中文等多字节字符进行正确截取。但是,使用 mb_substr 函数需要确保 PHP 已经加载了 mbstring 扩展。

25.php常见的魔术方法

PHP 魔术方法(Magic Method)是指在类中定义的特殊方法,用于在特定情况下自动调用,以完成一些特定的功能。

这些方法的名称都以 __ 开头和结尾,例如 __construct、__get、__set 等。下面列出了 PHP 中常见的魔术方法:

  1. __construct:类的构造方法,用于在对象创建时初始化成员变量等操作。
  1. __destruct:类的析构方法,在对象销毁时自动调用,可以用于清理资源等操作。
  1. __get:用于获取对象中不存在或者不可见的属性值,该方法需要定义一个参数,即要访问的属性名。
  1. __set:用于设置对象中不存在或者不可见的属性值,该方法需要定义两个参数,分别是要设置的属性名和属性值。
  1. __isset:用于检查对象中的属性是否存在,该方法需要定义一个参数,即要检查的属性名。
  1. __unset:用于删除对象中的属性,该方法需要定义一个参数,即要删除的属性名。
  1. __call:用于调用对象中不存在或者不可访问的方法,该方法需要定义两个参数,分别是要调用的方法名和方法参数。
  1. __callStatic:用于调用静态方法中不存在或者不可访问的方法,该方法需要定义两个参数,分别是要调用的方法名和方法参数。
  1. __toString:将对象转换为字符串时自动调用,通常用于输出对象的信息。
  1. __clone:在对象被克隆时自动调用,可以用于自定义克隆操作。

以上是 PHP 中常见的魔术方法,不同魔术方法的作用和参数不同,可以根据实际需求进行使用。

你可能感兴趣的:(git,php,redis,mysql)