【腾讯校园招聘笔试题技术类搜搜PHP笔试题解析】
1) **_autoload** 函数是 PHP 中的一个魔术方法,它的主要作用是在未先声明的情况下,自动加载类或接口对应的文件。当尝试实例化一个未定义的类或者调用一个未定义的接口时,如果已注册了 _autoload 函数,该函数就会被调用,传入未找到的类名或接口名作为参数。例如:
```php
function __autoload($className) {
require_once 'classes/' . $className . '.php';
}
```
上述代码会尝试在 classes 目录下加载对应类名的 PHP 文件。
2) **COOKIE 和 Session 的比较**
- **相同点**:两者都是用来存储用户状态信息的机制。
- **不同点**:
- 存储位置:COOKIE 存储在客户端(用户的浏览器),而 Session 存储在服务器端。
- 安全性:Session 比 COOKIE 更安全,因为数据不在客户端可见。
- 存储大小:COOKIE 一般限制在 4KB 左右,Session 存储空间相对较大。
- 生命周期:COOKIE 可以设置生命周期,也可以是持久化的;Session 默认会话结束即失效,但可以设置为持久化。
3) 下面的 PHP 代码创建了一个继承关系,类 B 继承自类 A,并重写了 func 方法。因此,当创建 B 类的对象并调用 func 方法时,将执行子类 B 中的方法,输出 "B"。
```php
class A {
function func() {
echo "A";
}
}
class B extends A {
function func() {
echo "B";
}
}
$obj = new B;
$obj->func();
```
4) **require 和 include 区别**
- require 会在文件找不到时产生致命错误(E_COMPILE_ERROR),而 include 会产生警告(E_WARNING),程序可以继续执行。
- require_once 和 include_once 分别会在已加载过文件时不再重复加载,避免重复引入。
5) **char 和 varchar 类型的区别**
- char 是固定长度的字符串类型,无论实际内容多长,都会占用指定的字符数。
- varchar 是可变长度的字符串类型,只占用实际字符数加上1或2个字节来存储长度(取决于数据库版本)。
- char 对于长度固定的字段更节省存储空间,而 varchar 更灵活且节省空间。
6) 在 MySQL 中,对于带有唯一索引的字段,以下 SQL 语句中,哪些可以利用索引来加速查询:
- A) `select * from UserInfo where USER = 'abc';` 可以使用索引。
- B) `select * from UserInfo where USER like '%abc';` 不能使用索引,因为是模糊匹配开头。
- C) `select * from UserInfo where USER like 'ab%c';` 不能使用索引,因为是模糊匹配中间。
- D) `select * from UserInfo where USER like 'abc%';` 可以使用索引。
- E) `select * from UserInfo where USER like '%abc%';` 不能使用索引,因为是模糊匹配结尾。
7) **编程题**
- 1. 冒泡排序:实现一个不依赖内置库的冒泡排序算法,基本思路是从数组的第一个元素开始,依次比较相邻元素,若前一个元素大于后一个,则交换它们的位置,重复此过程直到数组排序完成。
- 2. 去除字符串头尾空格:使用正则表达式 `^[\s]*([^\s]+)[\s]*$`,匹配并捕获非空格字符。
- 3. N 人报数游戏:可以使用一个循环和计数器,每次报数计数器加1,若为偶数则移除对应玩家,直至只剩一个人。
8) **算法设计:缓存系统**
设计一个高效的缓存系统,可以使用 LRU(Least Recently Used,最近最少使用)算法。当缓存满时,移除最近最少使用的对象。伪代码如下:
```
class LRUCache {
Map<Key, Node> cacheMap;
Queue<Node> lruQueue;
int capacity;
public LRUCache(int cap) {
capacity = cap;
cacheMap = new HashMap<>();
lruQueue = new LinkedList<>();
}
public Object get(Key key) {
if (cacheMap.containsKey(key)) {
moveToFront(lruQueue, key);
return cacheMap.get(key).value;
}
return null;
}
public void put(Key key, Object value) {
if (cacheMap.containsKey(key)) {
moveToFront(lruQueue, key);
cacheMap.get(key).value = value;
} else {
if (lruQueue.size() >= capacity) {
Key oldestKey = lruQueue.poll().key;
cacheMap.remove(oldestKey);
}
Node newNode = new Node(key, value);
lruQueue.add(newNode);
cacheMap.put(key, newNode);
}
}
private void moveToFront(Queue<Node> queue, Key key) {
Node node = cacheMap.get(key);
queue.remove(node);
queue.add(node);
}
}
class Node {
Key key;
Object value;
// constructor, getters and setters
}
```
在这个设计中,LRU 队列保存了缓存中的所有节点,最近使用的节点位于队列尾部。当添加新元素时,如果达到容量限制,就从队列头部(最不常使用的元素)移除。