真实面试题
文章目录
- php基础
- 1、什么是 PHP?如何安装和配置 PHP?
- 2、请解释 HTTP 协议及其工作原理
- 3、请简要解释 **MVC 模式**及其在 PHP 中的应用
- 4、您如何防止 PHP 应用程序遭受 XSS 和 SQL 注入等攻击
- 5、 PHP 中的 isset() 和 empty() 函数有什么区别(两个是反过来的)
- 6、tp和laravel框架之间的优缺点
- 7、 您如何处理 PHP 代码中的错误和异常?
- 8、如何调试 PHP 代码并查找问题?
- 9、请说明 PHP 中传值与传引用的区别,什么时候传值什么时候传引用
- 10、什么是面向对象?主要特征是什么?
- 11、SESSION 与 COOKIE的区别是什么
- 12、 表单中get和post提交方式的区别
- 13、语句include和require的区别是什么,为避免多次包含同一文件,可用什么语句代替它们?
- 14、PHP的基本变量类型
- 15、静态化如何实现的?伪静态如何实现?
- 16、说一下单引号双引号?
- 17、PHP 数组排序
- 18、PHP支持多继承吗
- 19、array_merge和array+array的区别
- 20、php安全性攻击(sql注入,xss攻击,CSRF攻击)
- 21、HTTP 状态中302、403、 500代码含义?
- 22、error_reporting这个函数有什么作用?
- 23、AJAX的优势是什么?
- 24、foo()和@foo()之间有什么区别?
- `*` 25、php的垃圾回收机制
- 26、echo、print_r、print、var_dump区别
- 27、PHP如何实现页面跳转
- 28、如果需要原样输出用户输入的内容,在数据入库前,要用哪个函数处理?
- ` (重要) ` 29、简述 private、 protected、 public修饰符的访问权限。
- 30、常用的魔术方法有哪些?举例说明
- 31、$this和self、parent这三个关键词分别代表什么?在哪些场合下使用?
- 32、作用域操作符::如何使用?都在哪些场合下使用?
- `(重要)`33、PHP遍历文件夹下所有文件(删除所有图片)
- 34、strtotime()函数的用法
- mysql面试题
- php框架:TP
- PHP框架:laravel
- 开发实际问题
- 算法
- 计算机网络
- Redis
- Linux
- 杂项
php基础
1、什么是 PHP?如何安装和配置 PHP?
PHP是一种开源的服务器端脚本语言,可用于创建动态网页和 Web 应用程序。安装和配置 PHP 取决于您使用的操作系统和 Web 服务器。
2、请解释 HTTP 协议及其工作原理
HTTP 是超文本传输协议。它通过互联网传输数据,并使用客户端/服务器模型工作。
3、请简要解释 MVC 模式及其在 PHP 中的应用
MVC 模式是 Model-View-Controller 的缩写,是一种软件设计模式,将应用程序分为三个核心部分:模型、视图和控制器。在 PHP 中,MVC 这些部分通常对应数据库、前端 UI 和后端逻辑。
4、您如何防止 PHP 应用程序遭受 XSS 和 SQL 注入等攻击
防止 XSS (跨站脚本攻击) 和 SQL 注入攻击的方法包括在输入验证中使用过滤器和转义字符,不信任用户输入并确保处理用户输入的方式正确。
5、 PHP 中的 isset() 和 empty() 函数有什么区别(两个是反过来的)
isset()函数检查变量是否存在且不为NULL,而empty()函数检查值是否为空。isset()返回布尔值true或false,而empty()可以像isset()一样返回布尔值,也可以返回整数0或字符串“0”。
isset() : 确定变量是否已设置且不为空;换句话说,仅当变量不为null时才返回true
empty() 函数是用于确定变量是否为空;换句话说,如果变量是空字符串,false,array(),NULL,“0”,0和未设置的变量,它将返回true。
6、tp和laravel框架之间的优缺点
TP框架擅长运行简单应用,而Laravel适合复杂项目。
但是Laravel的执行速度较慢,因为Laravel使用了大量的抽象层以及许多预处理程序等技术。
7、 您如何处理 PHP 代码中的错误和异常?
PHP 中的错误通过设置错误报告级别来处理。 可以通过在PHP代码中使用try和catch块获取并处理异常信息。
8、如何调试 PHP 代码并查找问题?
使用Xdebug地址调试PHP代码,并使用var_dump()和echo等函数查找问题,可输出变量值和状态信息,帮助您找到代码中的错误和问题。
9、请说明 PHP 中传值与传引用的区别,什么时候传值什么时候传引用
区别:
传值是参数的副本,不影响原始变量。
传引用是参数的引用,直接影响原始变量。
适用的场景:
传值适用于不需要修改原始变量的情况。
传引用适用于需要修改原始变量的情况。
10、什么是面向对象?主要特征是什么?
"面向对象是一种编程范式,
它将程序设计看作是对象的集合,通过封装、继承和多态等特性来组织和管理代码。
主要特征:
包括封装(隐藏内部细节)、继承(实现代码的重用和扩展)和多态(同一操作产生不同行为)。
面向对象的编程方法可以提高代码的安全性、可维护性和重用性,并提供更灵活和可扩展的代码架构。"
11、SESSION 与 COOKIE的区别是什么
Session:
存储在服务器端(运行着网站应用程序的计算机或服务器)
,相对安全,可以存储较大量的数据,但会在用户关闭浏览器或长时间不活动后过期
Cookie:
存储在客户端(用户使用的设备和浏览器)
,用户可以查看和修改COOKIE内容,存储容量较小,但可以设置过期时间,在指定时间之前一直存在。
12、 表单中get和post提交方式的区别
GET:
将数据附加在URL的查询字符串中传输,适合传输少量的非敏感数据,可以被缓存,但数据暴露在URL中存在安全风险。
POST:
将数据放在请求的正文中传输,适合传输大量数据和敏感信息,数据不会暴露在URL中,不会被缓存,可以引起服务器状态变化。
13、语句include和require的区别是什么,为避免多次包含同一文件,可用什么语句代替它们?
include:
如果include引入的文件不存在或引入过程中发生错误,PHP会发出警告,但脚本会继续执行。在执行过程中,如果多次引入同一个文件,PHP会发出多个警告,但脚本仍会继续执行。
require:
require引入的文件不存在或引入过程中发生错误,PHP会发出致命错误,并停止脚本的执行,如果多次引入同一个文件,PHP只会引入一次,不会发出错误。
可使用:require_once
、include_once
来之引入一次
使用场景:
使用require语句: 被包含的文件对于脚本的执行非常重要,且缺少该文件会导致脚本无法正常运行。
使用include语句: 如果被包含的文件只是提供了一些可选功能或资源,且缺少该文件不会导致脚本运行错误,
14、PHP的基本变量类型
- 字符串(String)
- 整数(Integer)
- 浮点数(Float)
- 布尔值(Boolean)
- 数组(Array)
- 对象(Object)
- 空值(Null)
- 资源(Resource):用于表示外部资源(如数据库连接、文件句柄等)的引用。
15、静态化如何实现的?伪静态如何实现?
静态化:
将动态生成的网页或内容转化为静态文件的技术手段,以提升网站性能和访问速度,
实现
:使用缓存技术和反向代理 实现
伪静态:
将动态URL转化为静态URL,以改善搜索引擎优化和用户体验。
实现
: 包括URL重写和MVC框架的路由配置。
16、说一下单引号双引号?
单引号字符串:
变量不会被解析,而会被直接输出。特殊字符(如换行符、制表符)会被转义,但其他转义字符(如 \n
和 \t
)不会生效。
双引号字符串:
变量会被解析并替换为其对应的值。特殊字符会被转义,同时转义字符也会生效
17、PHP 数组排序
sort():
按升序对数组的值进行排序,保持键与值的关联。该函数会改变原始数组,会重新索引数组的键
rsort():
按降序对数组的值进行排序,保持键与值的关联。该函数会改变原始数组,会重新索引数组的键
asort() ,arsort(): 分别对应升序和降序,都会改变原数组,不会重新索引数组的键
18、PHP支持多继承吗
直接的多继承是不被支持的,但是可以通过接口和特质来实现类似多继承的功能
通过接口,一个类可以实现一个或多个接口,从而拥有多个接口的行为和功能
19、array_merge和array+array的区别
键名为数字时:
array_merge()
不会覆盖掉原来的值,
但array+array
合并数组则会把最先出现的值作为最终结果返回,而把后面的数组拥有相同键名的那些值"抛弃"掉(不是覆盖),array+array 不会重新索引
20、php安全性攻击(sql注入,xss攻击,CSRF攻击)
1、SQL注入
使用PHP的内置mysql_real_escape_string()
函数用作任何用户输入的包装器。这个函数 对字符串中的字符进行转义,使字符串不可能传递撇号等特殊字符并让MySQL根据特殊字符进行操作。
2、跨站点脚本攻击(XSS攻击)
使用strip_tags()
函数,这个函数可以清除任何包围在HTML标记中的内容或者使用htmIlspecialchars()
函数。
3、跨站点请求伪造(CSRF)
Laravel框架中避免CSRF攻击很简单: Laravel自动为每个用户Session生成了一个CSRF Token,该Token可用于验证登录用户和发起请求者是否是同一人,如果不是则请求失败。
21、HTTP 状态中302、403、 500代码含义?
一二三四五原则:
(即一:消息系列;二:成功系列; 三:重定向系列;四:请求错误系列;五:服务器端错误系列。)
302: 临时转移成功,请求的内容已转移到新位置
403: 禁止访问
500: 服务器内部错误
401: 代表未授权。
22、error_reporting这个函数有什么作用?
设置PHP的报错级别并返回当前级别。
23、AJAX的优势是什么?
ajax是异步传输技术,可以通过javascript实现,也可以通过JQuery框架实现,实现局部刷新,减轻了服务器的压力,也提高了用户体验。
24、foo()和@foo()之间有什么区别?
@
代表所有warning忽略
*
25、php的垃圾回收机制
php中的变量存储在变量容器zval中,zval中除了存储变量类型和值外,还有is_ref
和refcount
字段。
refcount: 表示指向变量的元素个数,
is_ref: 表示变量是否有别名。
如果refcount为0时,就回收该变量容器。
如果一个zval的refcount减1之后大于0,它就会进入垃圾缓冲区。
当缓冲区达到最大值后,回收算法会循环遍历zval,判断其是否为垃圾,并进行释放处理。
26、echo、print_r、print、var_dump区别
echo: 语句结构;
print: 是函数,有返回值,用于输出字符串
print_r: 能打印数组,对象
var_dump: 能打印对象数组,并且带数据类型
27、PHP如何实现页面跳转
php函数跳转:,
缺点,header头之前不能有输出,跳转后的程序继续执行,可用exit中断执行后面的程序。
header("Location:网址");//直接跳转
header("refresh:3;url=http://www.jsdaima.com");//三秒后跳转
28、如果需要原样输出用户输入的内容,在数据入库前,要用哪个函数处理?
htmlspecialchars
或者htmlentities
(重要)
29、简述 private、 protected、 public修饰符的访问权限。
private : 私有成员, 只在类的内部才可以访问。
protected : 保护成员,该类内部和继承类中可以访问。
public : 公共成员,完全公开,没有访问限制。
30、常用的魔术方法有哪些?举例说明
php规定以两个下划线(__)开头的方法都保留为魔术方法
__construct() : 实例化类时自动调用。
__destruct() : 类对象使用结束时自动调用。
__set() : 在给未定义的属性赋值的时候调用。
__get() : 调用未定义的属性时候调用。
__isset() :使用isset()或empty()函数时候会调用。
__unset() :使用unset()时候会调用。
__sleep() :使用serialize序列化【将php序列化成字符】时候调用。
__wakeup() :使用unserialize反序列化的时候调用。
__call() :调用一个不存在的方法的时候调用。
__callStatic() :调用一个不存在的静态方法是调用。
__toString() :把对象转换成字符串的时候会调用。比如 echo。
__invoke() :当尝试把对象当方法调用时调用。
__set_state() :当使用var_export()函数时候调用。接受一个数组参数。
__clone() : 当使用clone复制一个对象时候调用。
31、$this和self、parent这三个关键词分别代表什么?在哪些场合下使用?
$this : 当前对象(使用->调用属性和方法)
self : 当前类 (使用 :: 调用)
parent : 当前类的父类
32、作用域操作符::如何使用?都在哪些场合下使用?
- 调用类常量
- 调用静态方法
(重要)
33、PHP遍历文件夹下所有文件(删除所有图片)
34、strtotime()函数的用法
第一个参数: 只要你能想到的英文日期他都有
**第二个参数:**基于哪个时间作为基准
// 将日期时间字符串转换为UNIX时间戳
$timestamp = strtotime('2023-05-30 10:30:00', time());
echo $timestamp; // 输出:1693205400
// 使用相对日期时间字符串
$nextWeek = strtotime('+1 week', time());
echo $nextWeek; // 输出:1693804400
// 使用相对日期时间字符串
$previousSunday = strtotime('-1 sunday', time());
echo $previousSunday; // 输出:1692924000
function deleteFiles($dir, $extensions) {
if ($handle = opendir($dir)) { // 打开目录句柄
while (false !== ($entry = readdir($handle))) { // 读取目录列表项
if ($entry == '.' || $entry == '..') { // 忽略 . 和 .. 目录
continue;
}
$path = $dir . '/' . $entry; // 获取文件的完整路径
if (is_dir($path)) { // 如果是目录,则递归调用自身处理子目录
deleteFiles($path, $extensions);
} else { // 如果是文件,并且扩展名匹配,则删除文件
/** 操作一: 单纯遍历文件
echo '文件:'.$path.'<br>';
**/
/** 操作二:删除图片
$ext = pathinfo($path, PATHINFO_EXTENSION); // 获取文件扩展名
if (in_array(strtolower($ext), $extensions)) { // 如果扩展名匹配,则删除文件
unlink($path);
}
**/
}
}
closedir($handle); // 关闭目录句柄
}
}
// 示例调用:删除jpg、png、gif类型的文件
deleteFiles('/path/to/directory', array('jpg', 'png', 'gif'));
mysql面试题
1、MySQL为什么使用B+树来作为其索引结构
-
因为是一颗有序树,并且B+树的叶子节点通过链表连接起,所以B+树支持高效的范围查询:
B+树按照键值大小有序地存储数据,每个叶子节点在同一层级上,可以支持非常高效的范围查询 -
B+树对于数据库随机写入性能极佳:
因为每个节点可以存储多个键和数据指针,**使得每次插入、删除或更新操作只需要修改少量节点(更少的磁盘io操作)**即可完成,这样就大大降低了写入时的开销。 -
B+树更适合写密集型场景(大量读写操作的场景):
由于非叶子节点仅保存索引信息,相比B树可以容纳更多子节点,因此B+树更适用于写密集型场景。
2、mysql中常见的锁
1、什么是行锁?:
行锁允许一个事务独占一行数据,其他事务无法修改该行数据直到该事务释放锁。
2、什么是表锁?
表锁是针对整张表的锁,允许一个事务独占该表的所有数据,其他事务无法修改该表的任何数据直到该事务释放锁。
3、什么是页锁?
页锁是针对数据页(一个存储块)的锁,允许一个事务独占某个数据页的所有数据,其他事务无法修改该数据页中任何数据直到该事务释放锁。
4、什么是共享锁?
共享锁是允许多个事务同时读取同一份数据,但是不能同时修改
该数据。共享锁可以提高并发读取性能。
5、什么是排他锁?
排他锁是一种独占锁,只允许一个事务修改数据。当一个事务持有排他锁时,其他事务无法对该数据进行读取或修改操作。
6、乐观锁和悲观锁【逻辑层面】
?
上述几种锁都是属于悲观锁(并发访问比较频繁且冲突概率较高的场景):
为数据可能会被其他事务修改,因此在读取或修改数据时会先对数据进行加锁,其他事务无法修改该数据直到当前事务释放锁
7、乐观锁:(多读少写的场景)
假设(原理)
多个事务访问同一份数据的概率很小,因此在进行更新操作时并不对数据进行加锁,而是先读取数据,并且记录下数据版本号
然后在写入数据时先检查数据版本是否与读取时记录的相同, 来判断本次操作是否可以成功执行。
3、该如何优化自己的sql
4、mysql有哪几种常见的索引
- Unique Index(唯一索引)
- Spatial Index(空间索引)
- Normal Index(普通索引)
B-tree索引或哈希索引
- 聚簇索引
- 非聚簇索引
5、什么场景需要设计索引
1、经常搜索的列:如果某个列经常被包含在 WHERE 或 JOIN 子句中,那么为该列添加索引可以提高查询速度。
2、频繁排序的列:
3、外键列: 外键列经常用于 JOIN 操作中,因此为其添加索引可以提高连接操作的速度。
4、唯一性约束列: 如用户ID 或电子邮件地址等,为其添加唯一性索引可以确保数据的完整性,避免重复数据的插入。
5、多表查询列: 如果查询需要多个表之间的联合,为跨表连接使用缩减查询时间和资源消耗的复合索引。
6、聚簇索引和非聚簇索引的区别
-
聚簇索引
(表数据与聚簇索引放在同一个B树节点里面)
:
查询效率高,找到了索引相当于找到了数据,但插入及更新操作的性能较低,因为需要重新排序 -
非聚簇索引
叶子节点不存储数据,存的是地址,即单独建立的另外一个B树持有索引数据
:
插入和更新的性能更好,但是查询时则需要进行两次IO,先读取索引再读取数据,因此查询速度相对聚簇索引稍慢一些
7、InnoDB 和 MyISM数据库引擎之间的区别
- InnoDB支持事务处理,而MyISAM不支持
(事务是对一组操作进行的原子性、一致性等保证,可以保证数据操作的正确性、可靠性和完整性)
2、InnoDB采用了行级锁定,而MyISAM采用的是表级锁定, 所以InnoDB并发操作时锁定的范围更小,从而提高了并发性能。
3、InnoDB支持 “外键” ,而 MyISAM 不支持
4、InnoDB使用B+树作为索引结构,支持聚簇索引
MyISAM使用B树或者哈希表作为索引结构,不支持聚簇索引,所以要先查索引文件在查数据文件。
8、事务的四大基本特性和隔离级别
事务的四大基本特性(ACID):
- 原子性: 事务作为一个整体,要么全部执行成功,要么全部失败回滚;
- 一致性: 事务执行前后,数据库都必须保持一致状态,不能破坏数据完整性和约束条件;
- 隔离性:事务之间的操作互不干扰,每个事务应该感觉不到其他并发事务的存在;
- 持久性: 一旦事务提交成功,所做的修改将会永久保存在数据库中
首先介绍一下mysql出现三种事务问题
幻读(Phantom Read)【别的事务插入和删除导致的】
是指在一个事务中,重复执行同一查询语句返回的结果集却不一致。通常是由于其他事务已插入或删除了符合该查询条件的数据。
脏读(Dirty Read)【读到未提交】
是指在一个事务中,读取到了另一个未提交的事务中更新的数据。如果另一个事务最终回滚,则当前事务读到的数据就是无效的。
不可重复读(Non-repeatable Read)【别的事物修改导致的】
是指在同一个事务中,重复执行同一查询语句,返回的结果集有所不同。通常是由于其他事务在两次查询之间修改了符合该查询条件的数据。
数据库的隔离级别有四种:
- 读未提交: 一个事务可以读取另一个事务尚未提交的数据,并可能导致脏读、幻读和不可重读的问题;
- 读已提交: 一个事务只能读取另一个事务已经提交的数据,避免了脏读的问题,但仍可能出现幻读和不可重读的问题;
- 可重复读: 一个事务在执行过程中多次读取同一行数据时,其结果是一致的,避免了脏读和不可重复读问题,但仍可能出现幻读的问题;
- 串行化: 所有事务都是串行执行的,避免了并发问题,但是会带来效率上的问题。
9、MySQL数据库中的字段类型varchar和char的主要区别是什么?
1.存储方式:
varchar是可变长度的,根据实际内容动态分配空间
char是固定长度的,始终占用预先分配的固定存储空间
空格处理:
CHAR会默认切掉字符串末尾的空格,而varchar不会
*
10、MySQL 遇到过死锁问题吗,你是如何解决的?
为了解决死锁,我采取了以下措施:
优化事务并发性、优化查询语句和索引、使用合理的事务管理策略、引入锁超时和重试机制以及调整数据库配置参数。通过这些方法,我成功降低了死锁发生的概率
11、MySQL 索引使用有哪些注意事项呢?
- 选择合适的列进行索引,针对常用的查询、连接和排序操作进行索引优化。
- 注意索引列的顺序,将最频繁使用的列放在索引的前面,以提高查询性能。
- 谨慎使用索引合并,评估是否使用索引合并来加速查询。
- 避免过度索引化,权衡索引数量和类型,避免过多索引对写操作的开销。
- 注意索引的维护成本,确保索引的收益超过维护成本。
- 定期分析和优化索引,识别潜在的性能问题并根据需求进行优化和重建。
- 使用合适的索引类型,根据查询需求和数据特性选择普通索引、唯一索引、主键索引等。
*
12、说说分库与分表的设计
都是数据库水平拆分的常用技术,用于解决大数据量和性能瓶颈问题
分库: 将数据按规则分散到多个数据库实例中,
考虑:
数据一致性和跨库事务。
分表: 将表按规则拆分为多个物理表,提升查询和写入性能,
考虑
: 注意跨表查询的复杂性。
*
13、在高并发情况下,如何做到安全的修改同一行数据?
乐观锁:
使用版本号或时间戳,在更新前先读取数据并比较版本号,确保一致后再执行更新操作。
悲观锁:
使用数据库的锁机制,获取独占锁来限制并发访问。
分布式锁:
使用分布式锁工具或基于数据库的锁机制,确保只有一个线程可以修改数据。
队列化操作:
通过消息队列按顺序处理需要修改同一行数据的操作,避免并发冲突。
14、如何通俗地理解三个范式?
用来规范化数据库设计的原则
第一范式:对属性的原子性约束,要求属性具有原子性,每一列的数据不可再分解;
第二范式:是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性,即非主键列完全依赖于表的主键;
第三范式:是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余。
php框架:TP
1、thinkphp5底层原理是什么
它的底层原理基于 MVC 架构模式。它通过路由系统将请求分发到对应的控制器和方法,处理用户请求和调度。同时,它提供了强大的请求和响应处理机制,方便解析请求参数和生成响应内容。此外,它还支持数据库访问和 ORM 功能(将数据库中的表映射为程序中的对象,使开发人员可以使用面向对象的方式操作数据)
,可以便捷地进行数据库操作。
2、thinkphp5 是怎么实现前后端分离
可以通过提供接口、配置路由、处理数据格式、支持跨域以及配合独立的前端框架等方式来实现前后端之间的协作
3、为什么tp5不用写路由,thinkphp5 怎么写接口
ThinkPHP 5框架内置了一种约定的路由规则,可以根据URL的路径和命名规则自动映射到对应的控制器和方法
需要创建一个控制器,定义接口方法,在方法中处理接口的逻辑和参数,返回相应的数据
4、thinkphp5请求类型是怎么设置的
可以使用 request->method('get'/’post‘)
来修改请求的类型
5、如何开启调试模式?调试模式有什么好处?
通过在 应用配置文件config.php
中设置 app_debug
参数为 true 来开启调试模式, 供详细的错误信息、SQL查询跟踪、自动重载代码等功能
6、TP中系统变量有哪些?如何获取系统变量
$_SERVER:
包含了服务器和执行环境的信息,如请求的URL、请求方法、服务器IP等。可以使用$_SERVER[‘变量名’]来访问。
$ _GET:包含通过GET方法提交的参数。可以使用$ _GET[‘变量名’]来访问。
$ _POST:包含通过POST方法提交的参数。可以使用$ _POST[‘变量名’]来访问。
$ _REQUEST:包含通过GET、POST和COOKIE方法提交的参数。可以使用$_REQUEST[‘变量名’]来访问。
$ _SESSION:包含当前会话中的会话变量。可以使用$ _SESSION[‘变量名’]来访问。
$ _COOKIE:包含通过COOKIE方法提交的参数。可以使用$ _COOKIE[‘变量名’]来访问。
$ _ENV:包含系统环境变量。可以使用$ _ENV[‘变量名’]来访问。
$ _FILES:包含通过文件上传提交的文件信息。可以使用$ _FILES[‘变量名’]来访问。
7、tp框架的联表操作
正向的:
-
一对一关联:hasOne()
$related:
关联的关联模型类名。
$foreignKey:
关联的外键字段,默认为当前模型名加 _id。
$localKey:
本地模型的主键字段,默认为 id。 -
一对多关联:hasMany()
$related:
关联的关联模型类名。
$foreignKey:
关联的外键字段,默认为当前模型名加 _id。
$localKey:
本地模型的主键字段,默认为 id。
反向的:belongsTo():
$related:
关联的主模型类名。
$foreignKey:
关联的外键字段,默认为关联模型名加 _id。
$localKey:
本地模型的主键字段,默认为 id。
PHP框架:laravel
开发实际问题
1、大流量的网站,采用什么样的方法来解决访问量问题?
可以采用增加服务器资源、负载均衡、数据库优化、缓存技术、异步处理、静态资源优化和代码优化等方法来解决 访问量问题
。
通过增加服务器能力、平衡负载、优化数据库和使用缓存等手段,可以提高网站的 并发处理能力
、减轻服务器压力,并提升用户体验
2、对缓存技术的了解?redis?
将计算结果、数据或对象存储在快速访问的存储介质中,缓存可以显著提高系统的响应速度和吞吐量,减少对后端数据源(如数据库)的访问次数,从而降低系统的负载
redis:
- 高性能: Redis将数据存储在内存中,因此具有极高的读写性能和低延迟。
- 数据持久化: Redis支持将数据持久化到磁盘,以防止数据丢失。
多数据结构支持: Redis支持多种数据结构和丰富的操作命令,使其适用于各种应用场景。
发布-订阅模式: Redis提供了发布-订阅功能,可以实现实时消息传递和事件通知。
高可用性: Redis支持主从复制和集群模式,以提供高可用性和容错能力。
*
3、redis和memcacahe、mongoDB的区别?
数据模型:
Redis 是键值存储系统,支持多种数据类型;
Memcache 也是键值存储系统,但仅支持简单的键值对;
MongoDB 是文档数据库,以类似JSON的BSON格式存储数据。
数据持久性:
Redis 可以将数据持久化到磁盘,支持数据恢复;
Memcache 不提供数据持久化功能,重启后数据丢失;
MongoDB 可以将数据持久化到磁盘,并支持数据复制和故障恢复。
查询和索引:
Redis 具有灵活的查询功能,支持索引和范围查询;
Memcache 不支持查询,只能通过键获取值;
MongoDB 支持复杂的查询语言和高级查询操作
算法
1、快速排序
<?php
function quick_sort(&$nums, $l, $r) {
if ($l >= $r) return;
$x = $nums[($l + $r) >> 1];
$i = $l - 1;
$j = $r + 1;
while ($i < $j) {
do $i++; while ($nums[$i] < $x);
do $j--; while ($nums[$j] > $x);
if ($i < $j) {
$temp = $nums[$i];
$nums[$i] = $nums[$j];
$nums[$j] = $temp;
}
}
quick_sort($nums, $l, $j);
quick_sort($nums, $j + 1, $r);
}
$nums = [1,5,2,4,9,3,7];
quick_sort($nums, 0, $n - 1);
foreach ($nums as $num) {
echo $num . ' ';
}
?>
2、冒泡排序
主要是注意第二重循环的次数为 $n - $i – 1 即可
function bubbleSort($arr) {
$n = count($arr);
for ($i = 0; $i < $n - 1; $i++) {
$swapped = false;
for ($j = 0; $j < $n - $i - 1; $j++) {
if ($arr[$j] > $arr[$j + 1]) {
// 交换位置
$temp = $arr[$j];
$arr[$j] = $arr[$j + 1];
$arr[$j + 1] = $temp;
$swapped = true;
}
}
// 如果没有发生交换,说明数组已经有序,可以提前结束排序
if (!$swapped) {
break;
}
}
return $arr;
}
// 测试示例
$nums = [5, 3, 8, 2, 1, 4];
$sortedNums = bubbleSort($nums);
print_r($sortedNums);
3、最接近的三数之和
思路:
1、首先对数据进行排序
2、定义一个循环,再定义两个双指针start和end,
3、在该循环下while一下,琼剧每次计算当前下标和两个指针之下的值相加是多少
3、多就左移动end,少就右移动start
<?php
function threeSumClosest($nums, $target) {
sort($nums);
$count = count($nums);
$ans = $nums[0] + $nums[1] + $nums[2];
for( $i=0;$i<$count;$i++) {
$start = $i+1; $end = $count - 1;
while($start < $end) {
$sum = $nums[$start] + $nums[$end] + $nums[$i];
if(abs($target - $sum) < abs($target - $ans)){
$ans = $sum;
}
if($sum > $target){
$end--;
}
else if($sum < $target){
$start++;
}
else{
return $ans;
}
}
}
return $ans;
}
var_dump(threeSumClosest(array(-1,2,1,-4,0),1));
?>
4、
(重点)
实现链表反转
<?php
//定义链表节点
class Node
{
private $value;
private $next;
public function __construct($value = null)
{
$this->value = $value;
}
public function getValue()
{
return $this->value;
}
public function setValue($value)
{
$this->value = $value;
}
public function getNext()
{
return $this->next;
}
public function setNext($next)
{
$this->next = $next;
}
}
//方法一:遍历,将当前节点的下一个节点缓存后更改当前节点指针
function reverse($head)
{
if ($head == null) {
return $head;
}
$pre = $head;//注意: 对象的赋值
$cur = $head->getNext();
$next = null;
while ($cur != null) {
$next = $cur->getNext();
$cur->setNext($pre);
$pre = $cur;
$cur = $next;
}
//将原链表的头节点的下一个节点置为null,再将反转后的头节点赋给head
$head->setNext(null);
$head = $pre;
return $head;
}
function test()
{
$head = new Node(0);
$tmp = null;
$cur = null;
// 构造一个长度为10的链表,保存头节点对象head
for($i=1;$i<10;$i++){
$tmp = new Node($i);
if($i == 1){
$head->setNext($tmp);
}else{
$cur->setNext($tmp);
}
$cur = $tmp;
}
//print_r($head);exit;
$tmpHead = $head;
while ($tmpHead != null) {
echo $tmpHead->getValue().' ';
$tmpHead = $tmpHead->getNext();
}
echo "\n";
//$head = reverse($head);
$head = reverse2($head);
while($head != null){
echo $head->getValue().' ';
$head = $head->getNext();
}
}
test();
?>
5、有效的括号
核心思路: 遇到左括号就压栈,遇到右括号就从栈中弹出匹配
function isValid($s) {
$length = strlen($s);
if ($length <= 1) {
return false;
}
//如果其中有空字符串或者字符串长度为奇数则为false
$ts = str_replace(" ",'',$s);
$tlen = strlen($ts);
if($length != $tlen || $length%2 != 0){
return false;
}
$tmp_arr = [")" => "(", "}" => "{", "]" => "["];
$arr = [];
for ($i=0; $i<$length; $i++) {
if (isset($tmp_arr[$s[$i]]) && $tmp_arr[$s[$i]] == end($arr)) {
array_pop($arr);
} else {
array_push($arr, $s[$i]);
}
}
return empty($arr) ? true : false;
}
var_dump($this->isValid("{[{]}"));
6、判断链表是否有环
核心思路:快慢指针
function hasCycle($head){
if($head == null) return null;
$slow = $head;
$fast = $head->next;
while($slow != $fast){
if($fast == null || $fast->next == null){
return false;//如果一直走没有环,从这个返回了
}
$slow = $slow->next;
$fast = $fast->next->next;
}
return true;
}
7、用php求取一个字符串中不重复的最长子串的方式
思路:
1、创建两个空数组,一个用于最终记录结果,一个用于记录当前的最长数组。
array_key_exists()
: 检查某个键名是否存在于数组中:
array_keys()
: 返回所有的键名
2、循环遍历,并且每一次循环都更新结果数组
<?php
$string = "1234567abcdaefaedkqatlmtx";
$len = strlen($string);
$resArr =[];
$tmp = [];
$i = 0;
while ($i < $len){
$char = $string{$i};
if(!array_key_exists($char, $tmp)){
$tmp[$char]= $i;
$i++;
if($i !== $len) continue;
}
//从重复值下个开始
$i = $tmp[$char]+1;
if( count($tmp) > count($resArr) ){
$resArr = $tmp;
}
$tmp = [];
}
echo implode(array_keys($resArr)); //结果:1234567abcd
?>
8 、统计两个数组相同数据的组数
思路:
1、定义一个临时数组先记录其中一个数组的值的出现情况
2、在用这个临时数组比较另外一个临时数组的数据出现情况
<?php
$f = [1, 3, 4, 7, 9];
$g = [3, 5, 7, 8, 10];
$temp = array();
foreach ($f as $val) {
$temp[$val] = isset($temp[$val]) ? ($temp[$val] + 1) : 1;
}
$count = 0;
foreach ($g as $val) {
if (isset($temp[$val])) {
$count += 1;
}
}
var_dump($count);
9、对两个升序数组进行合并
array_merge(数组1,数组2)
10、输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。
如果有多对满足要求,输出任意一对即可
思路:
1、先排好序,定义两个指针位于数组两端
2、开始循环,每次循环都判断一下当前位于指针的值加入来是否等于目标值
3、如果比目标值要大,右指针 - 1; 如果比目标值要小,左指针 + 1;
<?php
function twoSum($arr,$len,$sum)
{
$beg = 0;
$end = $len-1;
$curSum = 0;
while($beg < $end)
{
$curSum = $arr[$beg] + $arr[$end];
if($curSum == $sum)
{
var_dump($arr[$beg] ,$arr[$end],$sum);
$beg++;
$end--;
}
else if($curSum < $sum)
$beg++;
else
$end--;
}
}
$arr = [1,2,4,7,9,11,15,20,28,34];
twoSum($arr,count($arr),32);
计算机网络
一、浏览器输入URL到页面加载发生了什么
1、DNS解析:
把域名解析成对应的ip
2、浏览器与网站建立TCP连接(三次握手)
第一次握手:客户端向服务器端发送请求(SYN=1【表示请求建立连接】)
等待服务器确认;
第二次握手:服务器收到请求并确认,回复一个指令(SYN=1【表示同意建立连接】,ACK=1)
;
第三次握手:
客户端收到服务器的回复指令并返回确认(ACK=1,SYN=0 【表示连接已经建立】)
。
通过三次握手,建立了客户端服务器之间的连接,现在可以请求和传输数据了。
客户端问服务器:哥们你吃饭了么?
服务器回答客户端并且反问:我吃饭了,你呢?
客户端回答服务器:我也吃了。
3、请求和传输数据
4、浏览器渲染页面
5.链接结束(四次挥手):
客户端-→>服务端:请求完毕
服务端-→客户端:知道请求完毕
服务端->客户端:发送完毕
客户端→服务端:知道发送完毕
Redis
redis支持哪些数据结构
Redis支持字符串、哈希、列表、集合、有序集合和地理空间索引等数据结构
Linux
1、将本地某个端口映射到另外一个服务器的3306端口
使用ssh隧道进行端口的转发
ssh -L 3307:remote_server_ip:3306 user@local_server_ip
3307:remote_server_ip:3306:
表示将本地服务器的 3307 端口与远程服务器的 3306 端口进行映射。
这里的 remote_server_ip
需要替换为实际的远程服务器 IP 地址或域名。这个命令的作用是将本地服务器的 3307 端口转发到远程服务器的 3306 端口。
user@local_server_ip:
表示登录到本地服务器的用户名和 IP 地址。这里的 user
需要替换为实际的用户名,local_server_ip
需要替换为实际的本地服务器 IP 地址
2 、如何在Linux系统上查看和编辑文件?
查看文件内容:
cat filename
、more filename
、head filename
、tail filename
等。
编辑文件:
可以使用文本编辑器如vi、nano、vim等打开文件并进行编辑。
3、如何在Linux系统上查看和管理进程?
ps命令:
ps aux:
显示详细的进程列表,包括用户、CPU使用情况、内存占用等信息。ps -ef:
显示更简洁的进程列表,包括进程ID(PID)和父进程ID(PPID)等基本信息。
结束进程:
kill PID
命令可以终止具有特定进程ID(PID)的进程。
4、Linux中的权限管理是如何工作的?如何更改文件或目录的权限?
Linux中的权限管理是通过访问权限位来实现的,每个文件和目录都有所有者、所属组和其他用户的权限。可以使用chmod命令来更改文件或目录的权限
5、linux的定时任务怎么设置
- 输入以下命令以编辑当前用户的cron表:
crontab -e
- 根据cron表的格式,在打开的编辑器中添加定时任务。每一行代表一个定时任务,格式如下:
五个位置的符号分别对应(从左到右数)
- 分钟(Minute):取值范围为0-59,表示每小时的第几分钟执行任务。
- 小时(Hour):取值范围为0-23,表示每天的第几个小时执行任务。
- 日(Day of month):取值范围为1-31,表示每月的第几天执行任务。
- 月(Month):取值范围为1-12,表示每年的第几个月执行任务。
- 星期几(Day of week):取值范围为0-7(0和7都表示星期日),表示每周的第几天执行任务。
还可以使用以下 特殊字符
来表示时间字段的含义:
星号(*):匹配任意值,表示该字段不限制。
逗号(,):用于分隔多个值,表示在指定的多个值中任选一个。
中划线(-):用于表示范围,表示在指定范围内的所有值都满足条件。
正斜杠(/):用于指定步长,表示按照指定的步长增加值。
* * * * *:每分钟执行一次。
0 * * * *:每小时的第0分钟执行一次。
0 0 * * *:每天的凌晨0点执行一次。
0 0 * * 1:每周一的凌晨0点执行一次。
0 0 1 * *:每个月的1号凌晨0点执行一次。
0 0 1,15 * *:每个月的1号和15号凌晨0点执行一次。
0 0-8/2 * * *:每天的凌晨0点到8点之间,每隔2小时执行一次
(重要) 6、如何在Linux系统上查找文件或目录
- 使用find命令:
find命令递归地在指定路径下查找文件或目录。
find <路径> -name "<文件名或通配符>"
“<路径>”是要查找的起始路径,“<文件名或通配符>”是要查找的文件名或通配符模式。
例如:find . -name "*.txt"
2. 使用locate命令:
locate命令通过搜索系统的数据库来查找文件或目录。它通常比find命令快速,但可能不会显示最新创建的文件。
3. 使用grep命令:
grep命令用于在文件中搜索匹配指定模式的行。可以与其他命令(如find)结合使用来过滤查找结果。
经常用到的参数有:
-r:递归地搜索目录及其子目录中的文件。
-n:显示匹配行的行号。
-w:只匹配整个单词,而不是匹配包含模式的部分。
grep -rnw '<路径>' -e '<匹配模式>'
例如:grep -rnw '.' -e 'example'
(在当前目录及其子目录下查找包含关键字"example"的文件内容:)
7、 要在 Linux 中查找某一个进程(使用ps结合grep)
ps aux | grep <进程名或关键字>
例如:查找名为 "nginx" 的进程:
ps aux | grep nginx
8、使用ssh来连接服务器
ssh username@hostname
:
username 是您在远程主机上的用户名,hostname 是远程主机的 IP 地址或域名,按下回车后就会显示输入密码。
杂项
1、 Saas模式下的系统有什么不一样
SaaS模式下,用户不需要购买软件的许可证,而是通过订阅的方式使用软件。用户可以通过网页浏览器或特定的客户端应用程序访问云端的软件,并在云端进行数据存储和处理。
所以说,SaaS系统通常会使用云服务提供商来托管应用程序和数据