面试高频率问答题目

索引:

        主键索引:表的id   (唯一 且  不能为空)

        唯一索引:表User 假设有account 字段 ,用户名不重复  (唯一 可以为空)

        复合索引:where() 的条件 用户名,密码 (无要求,无要求)

锁:

        悲观锁:悲观锁的核心思想是假设在最坏的情况下,多个并发操作都会试图修改同一数据。因此,悲观锁会在操作数据之前先加锁,确保在解锁之前不会有其他线程或进程修改数据。这样,锁持有的期间,其他线程或进程无法访问该数据,直到锁被释放。(两个人同时想要去上厕所 只有一个厕所 , 只能A,B中的一个先上厕所即事务, 当上厕所的人 解决了后  剩下的人才能使用厕所)

例子:
假设商品ID为1的商品只剩下一件库存。用户A和用户B几乎同时发起购买这个商品的请求。
用户A开始一个事务,并执行SELECT * FROM products WHERE id = 1 FOR UPDATE;这个SQL语句。这个语句锁住了商品ID为1的记录,其他事务不能修改这个记录直到用户A的事务结束。
用户B开始一个事务,并试图执行同样的操作。但是,由于用户A已经加锁了该商品,用户B的查询会被阻塞,直到用户A释放锁。
悲观锁确保了用户A和用户B不会同时获得这件商品的购买资格,只有一个用户能够成功购买。

        乐观锁:乐观锁的核心思想是假设大多数情况下,多个并发操作不会冲突。乐观锁不会在操作数据前加锁,而是在数据更新时检查是否有其他线程或进程同时修改了数据。(在车站进站的时候,检票机【商城或者商品 】 在检测到用户 刷省份证的后  会进行 放行的行动    这个时候 A用户【大人】  B用户 【未成年 无身份证】 同时进入 。  在商品来讲就是超卖  原始库存10   即两个请求同时进行 在商品的数据的库存中-1  但是只会减1 【此时的库存为9】    )

用户A开始一个事务,并读取了商品ID为1的记录,此时不加锁。记录显示有10件库存。
用户B也开始一个事务,并读取了同样的记录,同样不加锁。记录也显示有10件库存。
用户A更新商品ID为1的记录的stock_quantity减1,并尝试提交事务。
用户B也更新商品ID为1的记录的stock_quantity减1,并尝试提交事务。
在用户A和用户B都尝试提交事务时,数据库会检查stock_quantity字段的值是否有冲突。由于两个人都减少了1件库存,现在库存量为9件。数据库会检查自事务开始以来数据是否有过变更。在这个例子中,由于两个人读取的数据是一样的,所以他们都认为库存量是10件,并且都进行了减1的操作。因此,他们都会成功提交事务,并不会因为库存量为9件而失败。

商品超卖问题  使用easyswoole 的消息队列来解决。

事务:事务是数据库中的一个重要功能,它允许一组数据库操作要么全部成功,要么全部失败。

rabbitmq:
RabbitMQ 是一个开源的消息队列系统,它实现了高级消息队列协议(AMQP)。AMQP 是一种消息传递中间件的标准协议,它定义了消息的传输、路由和队列机制。RabbitMQ 提供了跨语言和跨平台的客户端库,支持多种消息传递模式,包括点对点(Point-to-Point)、发布/订阅(Publish/Subscribe)和路由(Routing)

memache:

异步和同步是消息传递和数据处理中的两种常见模式,它们在不同的使用场景中有不同的优势和应用。
   异步
使用场景:
高并发处理:当系统需要处理大量并发请求时,异步处理可以避免阻塞,提高系统吞吐量。
非实时性要求:对于不要求实时响应的场景,如日志收集、数据分析等,异步处理可以background执行,不影响主线程。
解耦合:异步通信可以减少系统组件之间的耦合,使得系统更加模块化和灵活。
扩展性:异步模式便于扩展,可以通过增加消费者来处理更多的消息。
  优点:
提高系统响应速度和吞吐量。
减少资源占用,因为多个操作可以并行处理。
增强系统的伸缩性,可以通过增加处理线程或实例来处理更多的任务。
   缺点:
可能会引入复杂性,如消息队列的管理、消费者数量的调整等。
需要处理消息的顺序性和一致性问题。
可能会增加系统的复杂性,如错误处理、重试逻辑等。
   同步
使用场景:
实时性要求高:如在线交易处理、实时通信等,需要立即得到响应。
操作重要:对于关键操作,需要确保执行完毕才能进行后续操作。
数据一致性要求高:在需要确保数据一致性的场景中,同步操作可以保证操作的顺序性和一致性。
   优点:
保证操作的顺序性和一致性。
易于理解和实现,尤其是对于简单的单向操作。
适合需要即时反馈的场景。
  缺点:
可能会降低系统的并发能力,因为一个操作可能会阻塞其他操作。
资源占用较大,因为操作需要依次执行。
系统的伸缩性较差,因为增加负载通常需要增加服务器资源。

新建目录后,要执行的

php easyswoole.php server start
composer dump-autoload

composer dump-autoload
bstract class 和 class 在 PHP 中都是用来定义类的关键字,但它们之间有一些重要的区别:
    抽象类 (abstract class):
        不能被实例化。
        必须被继承。
        可以用 abstract 关键字定义没有实现体的方法(即纯虚方法)。
            目的是为了给出子类必须实现的方法规范。
    普通类 (class):
        可以被实例化。
        可以不用被继承。
        必须实现所有公共方法和属性(除非它们被声明为 static)。
        从你提供的代码片段来看,你已经在使用 abstract 类了。在这个上下文中:
        abstract class Base extends Controller 表明 Base 是一个抽象类,它继承自 Controller 类。
        abstract function onRequest(?string $action): ?bool 表明 onRequest 是一个抽象方法,它没有具体的实现,子类必须实现这个方法。
        抽象的使用方法:
        定义接口:当你想要定义一组方法,让继承你的类的子类必须实现这些方法时。
        代码复用和规范:当你有一组类共享同样的结构和行为,但具体实现不同的时候。
        基类:你可以创建一个抽象类作为其他类的基类,提供通用的方法和属性。
第一范式(1NF):
        第一范式的主要要求是属性原子性,也就是说,表中的每个字段都应该是不可再分的最小数据单位。这与主键或外键的概念无关。1NF确保了字段内的数据是单一的,不包含多个值或者字符串集合。

    假设我们有一个表叫做Students,它包含学生的信息。在1NF的要求下,每个字段都应该包含一个不可再分的值。例如,如果我们想要存储学生的全名,我们不能将名字和姓氏分开存储,而应该有一个字段FullName来存储完整的名字。
    复制
    Students
    +--------+------------+------+
    | ID     | FullName   | ... |
    +--------+------------+------+
    | 1      | John Doe   | ... |
    | 2      | Jane Smith | ... |
    +--------+------------+------+
    在这个例子中,FullName字段包含的是学生的完整名字,它是一个不可再分的值。
第二范式(2NF)
        第二范式在第一范式的基础上增加了唯一性的要求,即表中的每条记录都应该有一个唯一的主键,并且表中的所有非主键字段都必须完全依赖于主键,而不是仅依赖于主键的一部分(即组合键)。这里的“依赖于”意味着如果删除某条记录,那么与这条记录相关的所有其他记录都应该被删除,以保持数据的引用完整性。第二范式与外键的概念相关,因为它涉及到表之间的引用关系,但它们并不是相同的事物。
(学生表和课程表  ,在课程表中  想要知道某学生和他的课程 学生相关信息的字段依赖于课程的字段,每个学生的课程都因该与特定的课程关联 比如说学生的课程 web开发  特定的课程 web开发 xx老师授课 )
 
    现在,让我们假设我们还有一个表叫做Courses,它包含学生选修的课程信息。在2NF的要求下,每个表都应该有唯一的主键,并且表中的所有非主键字段都必须完全依赖于主键。

    复制
    Courses
    +--------+---------+------+
    | Course | Student | ... |
    +--------+---------+------+
    | Math   | 1       | ... |
    | Physics| 1       | ... |
    | History| 2       | ... |
    +--------+---------+------+
    在这个例子中,Student字段依赖于Course字段,因为每个学生选修的课程都应该与特定的课程关联。这里我们可以给Courses表添加一个主键,比如CourseID。
第三范式(3NF)
    最后,3NF要求表中的所有字段不仅依赖于主键,而且它们的值不能被其他字段所派生。这意味着表中的每个字段都应该是独立的,不应该包含可以从其他字段计算得出的数据。
    假设我们想要存储每个课程的教师信息。如果我们有一个Teachers表,它包含教师的详细信息,我们不能在Courses表中重复教师的详细信息。
    
    Teachers
    +--------+---------+------+
    | Teacher| Course  | ... |
    +--------+---------+------+
    | Smith  | Math    | ... |
    | Brown  | Physics | ... |
    | Jones  | History | ... |
    +--------+---------+------+
    在这个例子中,Courses表中的Teacher字段依赖于Teachers表中的Teacher字段。因此,我们应该在Courses表中使用一个外键TeacherID来引用Teachers表的主键TeacherID。
    通过遵循这三个范式,我们可以确保数据库中的数据是规范化的,这样可以减少数据冗余,提高数据的一致性和完整性。

          MySQL数据库作发布系统的存储,一天五万条以上的增量,预计运维三年,怎么优化? 

                1:硬件方面: 增加cpu ,内存,硬盘

                2:使用redis减少 对数据库的查询。

                3:使用合适的数据库引擎 InnoDb 。

                4:设置索引,优化索引 ,优化sql

                5:分区,分表。

                6:读写分离。

        对于大流量的网站,您采用什么样的方法来解决各页面访问量统计问题?

                1:限流:

                        令牌桶算法,漏桶算法,。

                2:采用分布式系统。

                3:队列处理。

                4:数据库缓存。

use think\facade\Redis;
// 实例化 Redis 对象
$redis = Redis::instance();
// 连接到 Redis 服务器
$redis->connect('127.0.0.1', 6379, 1); // 1秒超时
// 开始事务
$redis->multi();
// 执行事务中的命令
$redis->set('key1', 'value1');$redis->set('key2', 'value2');
// 执行事务
$result =$redis->exec();
// 检查事务执行结果
if ($result) {
    // 所有命令成功执行
    echo "Transaction successful.";
} else {
    // 事务中有命令执行失败
    echo "Transaction failed.";
}
// 关闭 Redis 连接
$redis->close();

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值