一些面试题
PHP面试题
PHP基础
1. 请写出以下结果:
echo json_encode(['a' => 1] + ['b' => 2, 'a' => 3, 'b']);
//输出:
$param = 1;
$funcA = function ($val) use (&$param) {
$param++;
return $param + $val;
};
$funcB = function () use ($param) {
$param++;
return $param;
};
var_dump($funcA(2)); //结果:
var_dump($funcB()); //结果:
var_dump($param); //结果:
2. 请说明以下常见错误:
Notice: Undefined variable: test
Fatal error: Uncaught Error: Class 'Foo\Test' not found
Fatal error: Uncaught Error: Call to a member function abc() on null
Fatal error: Uncaught Error: Call to undefined method Test::abc()
Fatal error: Uncaught ArgumentCountError: Too few arguments to function Test::abc()
Parse error: syntax error, unexpected ';', expecting ']'
3. 写出以下 PHP 魔术方法含义
__callStatic()
__toString()
__invoke()
__sleep()
PHP应用
1. 请说明以下使用哪种设计模式
- 设计模式1:单例
class Test1 {
protected static $instance;
public static function getInstance() {
if (! self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
}
- 设计模式2:工厂
class Test2 {
public function factory($config) {
return new self($config);
}
}
- 设计模式3:观察者
class Reader implements SplObserver {
public function update(SplSubject $subject) {
echo $subject->title;
}
}
class News implements SplSubject {
private $observers = [];
public function attach(SplObserver $observer) {
$this->observers[] = $observer;
}
public function detach(SplObserver $observer) {}
public function notify() {
foreach ($this->observers as $obj) {
$obj->update($this);
}
}
}
2. 你所知道的 PSR 规范有哪些,并说明其作用:
PHP-FIG(PHP Framework Interop Group)是一个由PHP社区组成的组织,旨在制定PHP编程规范,以促进PHP开发社区的互操作性和标准化。其中,PSR(PHP Standard Recommendation)规范是PHP-FIG定义的一系列PHP编程规范,用于指导PHP开发者编写更加标准化和可维护的代码。
以下是一些常见的PSR规范及其作用:
-
PSR-1:基本编码规范
- 定义了PHP代码文件应该使用的基本编码规范,如命名空间、类名、文件命名等,以确保代码的一致性和易读性。
-
PSR-2:代码风格规范
- 规定了PHP代码的排版风格,包括缩进、空格、换行等,以提高代码的可读性和一致性。
-
PSR-3:日志接口规范
- 定义了一个通用的日志接口,使不同的日志库可以互相替换,提高代码的灵活性和可移植性。
-
PSR-4:自动加载规范
- 规定了PHP命名空间与文件路径的映射规则,以实现更加方便和高效的自动加载机制。
-
PSR-7:HTTP消息接口规范
- 定义了HTTP消息的接口规范,包括请求和响应对象的创建、处理和操作方式,以实现更加灵活和可扩展的HTTP消息处理。
这些PSR规范有助于提高PHP代码的质量、一致性和可维护性,促进不同PHP项目之间的互操作性和协作。遵循PSR规范可以使开发者编写出更加规范和易于理解的PHP代码,提高代码的可读性和可维护性,同时也有助于减少代码错误和提高代码的可移植性。
3. 说明 composer global require
与 composer require
区别
composer global require
和composer require
是Composer命令行工具中两个常用的命令,它们之间有一些区别:
-
composer global require
:- 作用:用于全局安装Composer包,安装的包会被放置在Composer的全局安装目录中,而不是当前项目的vendor目录下。
- 使用场景:适合安装一些全局可用的Composer包,比如命令行工具、代码生成器等,可以在任何项目中使用。
- 例子:
composer global require laravel/installer
-
composer require
:- 作用:用于在当前项目中安装Composer包,安装的包会被放置在当前项目的vendor目录下。
- 使用场景:适合安装当前项目所需的依赖包,包括框架、库、工具等。
- 例子:
composer require guzzlehttp/guzzle
总的来说,composer global require
用于全局安装Composer包,可以在任何项目中使用,而composer require
用于在当前项目中安装Composer包,只在当前项目中生效。根据具体的需求和使用场景选择合适的命令来安装Composer包。
4. 在 composer.json 中依赖包有说明版本,请说明以下语义化版本的意思:
"^1.2.3"
"~1.2.3"
波浪符号(~):他会更新到当前minor version(也就是中间的那位数字)中最新的版本。放到我们的例子中就是:body-parser:~1.15.2,这个库会去匹配更新到1.15.x的最新版本,如果出了一个新的版本为1.16.0,则不会自动升级。波浪符号是曾经npm安装时候的默认符号,现在已经变为了插入符号。
插入符号(^):这个符号就显得非常的灵活了,他将会把当前库的版本更新到当前major version(也就是第一位数字)中最新的版本。放到我们的例子中就是:bluebird:^3.3.4,这个库会去匹配3.x.x中最新的版本,但是他不会自动更新到4.0.0。
网络协议/服务
1. HTTP协议中几个状态码的含义
- 204
- 301
- 401
- 403
- 404
- 405
- 500
2. 请看以下HTTP数据流, 写出PHP代码如何接收以下HTTP POST的内容数据和Query参数, 并按响应结果写出相应的执行代码:
POST /index.php?ccc=123 HTTP/1.1
Host: localhost
Content-Type: application/json
Accept: application/json
Content-Length: 28
{"aaa":"test","bbb":[1,2,3]}
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 40
{"aaa":"test","bbb":[1,2,3],"ccc":"123"}
3. 请写一个 Restful 设计风格的增删改查(CURD)接口写法
如,获取所有用户列表: GET /users
请写出相应的增删改:
4. 请说明下优化 Mysql sql 查询的技巧和做法
优化MySQL SQL查询是提高数据库性能的关键之一。以下是一些优化MySQL SQL查询的常见技巧和做法:
-
使用索引:确保表中经常用于查询的列上有合适的索引。索引可以加快查询速度,减少数据检索的时间。
-
避免SELECT *:尽量避免使用SELECT *来检索所有列。只选择需要的列可以减少数据传输量和查询时间。
-
避免使用子查询:尽量避免使用子查询,可以考虑使用连接(JOIN)来代替子查询,连接通常更有效率。
-
使用EXPLAIN命令:使用EXPLAIN命令可以查看查询的执行计划,帮助分析查询性能问题,优化索引或查询语句。
-
避免使用OR条件:使用OR条件会使查询变得复杂,可以考虑使用IN或者UNION来代替OR条件。
-
避免使用ORDER BY RAND():避免使用ORDER BY RAND()来随机排序结果,这会导致性能问题。可以考虑使用其他方法来获取随机结果。
-
使用LIMIT限制结果集:在查询中使用LIMIT可以限制返回的结果集大小,减少数据传输量和查询时间。
-
避免使用SELECT DISTINCT:尽量避免使用SELECT DISTINCT来去重查询结果,可以考虑使用GROUP BY来代替。
-
定期优化表结构:定期检查表结构,删除不必要的索引,优化表结构,可以提高查询性能。
-
缓存查询结果:对于一些查询结果不经常变化的情况,可以考虑使用缓存来存储查询结果,减少数据库查询次数。
以上是一些常见的优化MySQL SQL查询的技巧和做法,通过合理使用索引、避免不必要的查询、优化查询语句等方法,可以提高数据库查询性能,提升应用程序的响应速度。
5. Mysql 的 innodb 引擎与 MyISAM 引擎哪些区别
6. 请写出Linux常用操作命令
- 显示某文件末尾几行
tail -n 20或者sed方法 -n 可以查看行以及搜索特定字符
- 文件内容关键字搜索
sed -n '/name/'p filename
- 查看当前进程
ps aux 或者查看某XXX进程 ps -ef | grep xxx
- 下载某URL文件
wget -c http://baidu.com/aaa.rar -c 支持断点续传
- 网络抓包
tcpdump tcp port 23 host 210.27.48.1(获取主机210.27.48.1接收或发出的telnet包)
7. 请写出以下服务的用途
- CDN 内容分发网络 可以将静态文件放在cdn上减少因网络问题带来的延迟,功能服务器压力减小。
- LVS linux虚拟服务器 负载集群使用
- HaProxy
前端
- 有
a.js
和b.js
请用 CMD 或 AMD 模块化规范写出b.js
如何引用a.js
.
在使用CMD(Common Module Definition)或AMD(Asynchronous Module Definition)模块化规范时,可以通过模块加载器(如RequireJS)来实现模块之间的引用和依赖关系。下面是示例代码,展示了如何在b.js
中引用a.js
:
假设a.js
和b.js
的内容如下:
a.js:
define(function(require) {
var a = {
showMessage: function() {
console.log('Hello from a.js');
}
};
return a;
});
b.js:
define(function(require) {
var a = require('./a');
var b = {
init: function() {
a.showMessage();
console.log('Hello from b.js');
}
};
return b;
});
在上面的代码中,a.js
使用define
定义了一个模块,并在模块中定义了一个showMessage
方法。在b.js
中,使用define
定义了另一个模块,并通过require('./a')
来引入a.js
模块。然后可以直接调用a
对象中的showMessage
方法。
在实际应用中,可以使用RequireJS等模块加载器来加载和管理这些模块,确保模块之间的依赖关系正确并且能够按需加载。这样可以提高代码的可维护性和可扩展性,同时遵循模块化规范。
-
你所使用的构建工具是(glup, grunt, webpack) ?
-
请写出 es6 的新语法特性(至少3个)
ES6(ECMAScript 2015)是JavaScript的一个重要更新版本,引入了许多新的语法特性和功能。以下是ES6的一些新语法特性:
-
箭头函数(Arrow Functions):
- 箭头函数是一种更简洁的函数定义方式,可以用
=>
来定义函数。 - 示例:
const add = (a, b) => a + b;
- 箭头函数是一种更简洁的函数定义方式,可以用
-
解构赋值(Destructuring Assignment):
- 解构赋值允许从数组和对象中提取值,赋值给变量。
- 示例:
const [a, b] = [1, 2];
-
模板字符串(Template Strings):
- 模板字符串可以包含变量和表达式,使用反引号(``)包裹。
- 示例:
const name = 'Alice'; console.log(`Hello, ${name}`);
-
let 和 const 声明:
- let和const是用来声明变量的新关键字,let声明的变量具有块级作用域,const声明的变量是常量。
- 示例:
let count = 0; const PI = 3.14;
-
类和继承(Classes and Inheritance):
- ES6引入了class关键字,可以更方便地创建类和实现继承。
- 示例:
class Animal { constructor(name) { this.name = name; } speak() { console.log(`${this.name} makes a noise.`); } }
以上是ES6的一些新语法特性,包括箭头函数、解构赋值、模板字符串、let和const声明、类和继承等。这些新特性使得JavaScript更加现代化、易读易写,提高了开发效率和代码质量。
a.com/index.html
访问b.com/api.php
的数据, 遇到跨域问题, 请写出在 HTML5中的跨域解决方案
在HTML5中,可以通过以下几种方式来解决跨域问题:
-
CORS(跨域资源共享):
- CORS是一种通过在服务器端设置响应头来允许跨域请求的机制。在服务器端设置
Access-Control-Allow-Origin
等相关响应头,指定允许访问的域名,从而实现跨域资源共享。 - 示例:在
b.com/api.php
的响应头中添加Access-Control-Allow-Origin: http://a.com
。
- CORS是一种通过在服务器端设置响应头来允许跨域请求的机制。在服务器端设置
-
JSONP(JSON with Padding):
- JSONP是一种利用script标签的跨域请求方式,通过动态创建script标签,设置src为跨域接口地址,并定义一个回调函数来处理返回的数据。
- 示例:在
a.com/index.html
中创建一个script标签,src指向b.com/api.php?callback=handleData
,并定义handleData
回调函数来处理返回的数据。
-
WebSocket:
- WebSocket是HTML5提供的一种新的协议,可以实现跨域通信。通过在服务器端开启WebSocket服务,可以在客户端与服务器之间建立持久性的双向通信。
- 示例:在
a.com/index.html
中使用WebSocket对象与b.com
的WebSocket服务进行通信。
-
代理服务器:
- 可以通过在同源服务器端设置代理服务器来转发跨域请求,即由同源服务器向目标服务器发送请求,然后再将数据返回给客户端,避免跨域问题。
- 示例:在同源服务器端设置一个代理服务器,将
a.com/index.html
发送的请求转发到b.com/api.php
,然后将数据返回给客户端。
以上是在HTML5中常用的跨域解决方案,根据具体情况选择合适的方式来解决跨域问题。需要注意的是,要确保跨域请求的安全性和合法性,避免出现安全漏洞。
综合
如何看待前后端分离, 如果让你设计一前后端分离的后台管理系统, 你会运用哪些前后端的应用库和设计结构.
前后端分离是一种流行的架构设计模式,通过将前端和后端分离开发,可以提高系统的灵活性、可维护性和扩展性。设计一前后端分离的后台管理系统时,可以运用以下前后端应用库和设计结构:
-
前端技术栈:
- Vue.js或React:作为前端框架,用于构建用户界面和实现页面交互。
- Vuex或Redux:用于管理前端应用的状态,实现状态管理和数据流控制。
- Element UI或Ant Design:用于构建UI界面和组件库,提供丰富的UI组件和样式。
- Axios:用于处理前端与后端的HTTP请求,实现数据的获取和交互。
-
后端技术栈:
- Node.js或Spring Boot:作为后端框架,用于处理业务逻辑和数据处理。
- Express或Spring MVC:用于构建后端API接口,处理前端请求和返回数据。
- MongoDB或MySQL:作为数据库存储数据,实现数据持久化和管理。
-
设计结构:
- RESTful API:采用RESTful风格设计API接口,实现前后端数据交互和通信。
- MVC架构:采用MVC(Model-View-Controller)架构模式,将前端视图、后端逻辑和数据模型进行分离,提高系统的可维护性和扩展性。
- JWT认证:使用JWT(JSON Web Token)进行用户认证和授权管理,保护系统安全性。
-
其他工具和技术:
- Git:用于版本控制和团队协作。
- Webpack:用于打包前端资源,实现代码压缩和优化。
- Docker:用于容器化部署应用,提高开发和部署效率。
以上是设计一前后端分离的后台管理系统时可以运用的前后端应用库和设计结构。根据具体需求和项目情况,可以选择合适的技术栈和工具,以实现系统的高效开发和稳定运行。同时,要注重前后端的协作和沟通,确保系统的整体一致性和性能优化。