整理了一份招PHP高级工程师的面试题

嗯,基本上这些题都答得好 那就…
直接上题.

1. 基本知识点

  1. HTTP协议中几个状态码的含义:503 500 401 200 301 302。。。
  2. Include require include_once require_once 的区别.
  3. PHP/Mysql中几个版本的进化史,比如mysql4.0到4.1,PHP 4.x到5.1的重大改进等等。
  4. HEREDOC介绍
  5. 写出一些php魔幻方法;
  6. 一些编译php时的configure 参数
  7. 向php传入参数的两种方法。
  8. (mysql)请写出数据类型(int char varchar datetime text)的意思; 请问varchar和char有什么区别;
  9. error_reporting 等调试函数使用
  10. 您是否用过版本控制软件? 如果有您用的版本控制软件的名字是?
  11. posix和perl标准的正则表达式区别;
  12. Safe_mode 打开后哪些地方受限.
  13. 写代码来解决多进程/线程同时读写一个文件的问题。
  14. 写一段上传文件的代码。
  15. Mysql 的存储引擎,myisam和innodb的区别。

2. web 架构,安全,项目经验

  1. 介绍xdebug,apc,eAccelerator,Xcache,Zend opt的使用经验。
  2. 使用mod_rewrite,在服务器上没有/archivers/567.html这个物理文件时,重定向到index.php?id=567 ,请先打开mod_rewrite.
  3. MySQL数据库作发布系统的存储,一天五万条以上的增量,预计运维三年,怎么优化?
  4. 写出一种排序算法(原理),并说出优化它的方法。
  5. 请简单阐述您最得意的开发之作
  6. 对于大流量的网站,您采用什么样的方法来解决各页面访问量统计问题
  7. 您是否用过模板引擎? 如果有您用的模板引擎的名字是?
  8. 请介绍Session的原理,大型网站中Session方面应注意什么?
  9. 测试php性能和mysql数据库性能的工具,和找出瓶颈的方法。
  10. 正则提出一个网页中的所有链接.
  11. 介绍一下常见的SSO(单点登陆)方案(比如dedecms整合discuz的passport)的原理。
  12. 您写过的PHP框架的特点,主要解决什么问题,与其他框架的不同点。
  13. 大型的论坛/新闻文章系统/SNS网站在性能优化上有什么区别?
  14. 相册类应用:要求在浏览器中能同时选中并上传多个文件,图片要求能剪裁,压缩包在服务器端解压。能上传单个达50M的文件。上传过程中有进度条显示。每个图片能生成四种大小缩略图,视频文件要转成flv供flash播放。叙述要涉及的各类开源软件和简单用途。
  15. 一群猴子排成一圈,按1,2,…,n依次编号。然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,在把它踢出去…,如此不停的进行下去,直到最后只剩下一只猴子为止,那只猴子就叫做大王。要求编程模拟此过程,输入m、n, 输出最后那个大王的编号。用程序模拟该过程。

3. unix/linux 基本使用

  1. linux下查看当前系统负载信息的一些方法。
  2. vim的基本快捷键。
  3. ssh 安全增强方法;密码方式和rsa key 方式的配置。
  4. rpm/apt/yum/ports 装包,查询,删除的基本命令。
  5. Makefile的基本格式,gcc 编译,连接的命令,-O0 和-O3区别。
  6. gdb,strace,valgrind的基本使用.

4. 前端,HTML,JS

  1. css盒模型。
  2. javascript中的prototype。
  3. javascript中this对象的作用域。
  4. IE和firefox事件冒泡的不同。
  5. 什么是怪异模式,标准模式,近标准模式。
  6. DTD的定义
  7. IE/firefox常用hack.
  8. firefox,IE下的前端js/css调试工具。

测试FusionIO:strict_sync太秀逗了…

这是一篇译文,原文地址是:   http://www.mysqlperformanceblog.com/2009/06/15/testing-fusionio-strict_sync-is-too-strict/

随着新的更新FusionIO驱动的更新,我能够在我的戴尔R900与Ubuntu 8.10上进行尝鲜,而不再需要痛苦地编译驱动或是降级kernel.现在我决定测试一下strict_sync模式。

据我所知FusionIO默认情况下,比如英特尔的SSD ,是对应用程序“撒谎”了,fsync()并不是真正的发生了,它仍然只是提交到了内存而不是最终的磁盘。FusionIO还有一个“ strict_sync ”模式,可以保证fsync函数可靠地操作。

好啊兄弟,让我们来压一下性能—通常我在100w数据(约9GB数据),O_DIRECT模式下开着3GB的buffer_pool来搞这个测试。
原始测试数量参见这里
pub
结果用TPM (每分钟的事务数)表示 ,这样更清楚一些。图形显示,结果是是随着时间[X轴]不断变化 。
这个图形已经很明显,我都不需要再用文字来说明了。。。

但是我没有测试,在断电的情况下,在默认模式下处理、结束事务的情况。这个需要读者您检查一下。

怎样用一行脚本美化/etc/my.cnf文件

原文地址:http://www.mysqlperformanceblog.com/2009/06/15/how-to-pretty-print-mycnf-with-a-one-liner/
当我在一台服务器上转悠时,我会经常想看看/etc/my.cnf文件格式,当然是想看格化美观,没有注释的。这样的一行Perl就能将美化输出文件:

1.perl -ne ‘m/^([^#][^s=]+)s*(=.*|)/ && printf(“%-35s%sn”, $1, $2)’ /etc/my.cnf
2.[client]
3.port = 3306
4.socket = /var/run/mysqld/mysqld.sock
5.[ mysqld_safe ]
6.socket = /var/run/mysqld/mysqld.sock
7.nice = 0
8.[ mysqld ]
9.user = mysql
10.pid-file = /var/run/mysqld/mysqld.pid
11.socket = /var/run/mysqld/mysqld.sock
12.port = 3306
13…..

缓慢的drop table 操作

原文地址:http://www.mysqlperformanceblog.com/2009/06/16/slow-drop-table/

大家都知道,Ext3并不是最有效的文件系统,例如,删除文件会非常缓慢(那真是一个痛苦的过程,不是吗老兄?),造成大量的随机I / O。然而事实上,有时候它比你想象的更能影响MySQL的性能。那么,什么时候会发生,又为什么会发生呢?

当您运行DROP TABLE时,会有好几件事情需要去做:对表进行write lock,这样它不会被其他线程使用;存储引擎删除数据文件;当然,最后MySQL会删除表定义文件(.frm文件)。这还不是所有的事,还有另外一件事需要去做:

  1. VOID(pthread_mutex_lock(&LOCK_open));
  2. error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0);
  3. pthread_mutex_unlock(&LOCK_open);

这整段删除表操作的代码都被LOCK_open互斥信号量所包围。这个互斥信号量在MySQL中不少地方都用到过,但主要是表在开启或关闭的时候。这意味着,当LOCK_open锁定时,没有查询语句可以执行,因为他们阻止任何访问。

这就解释了在ext3文件系统上删除10GB的文件何时成为了痛苦的等待的开始。删除10GB的文件将持续一段时间,如果这是一个MySQL表,这段时间mutex里将会一直存在,而这个互斥会拖延所有查询。

代码:

  1. +—–+——+———–+——+———+——+ —————-+——————————— —————+
  2. | Id | User | Host | db | Command | Time | State | Info |
  3. +—–+——+———–+——+———+——+ —————-+——————————— —————+
  4. | 1 | root | localhost | test | Query | 7 | NULL | drop table large_table |
  5. | 329 | root | localhost | test | Query | 7 | Opening tables | select sql_no_cache * from other_table limit 1 |
  6. +—–+——+———–+——+———+——+ —————-+——————————— —————+

我尝试了一些替代的办法,让MySQL来在DROP TABLE时删除小文件,以尽量减少影响,如:

  • TRUNCATE TABLE large_table; ALTER TABLE large_table ENGINE=…; DROP TABLE large_table;
  • TRUNCATE TABLE large_table; OPTIMIZE TABLE large_table; DROP TABLE large_table;

不幸的是,原来所有管理指令:ALTER TABLE <ALTER ALTER TABLEOPTIMIZE TABLE实际都一样,或是在旧的表文件删除时使用了其他的LOCK_open互斥信号锁。

代码:

  1. | 3 | root | localhost | test | Query | 7 | rename result table | ALTER TABLE large_table ENGINE=MyISAM |
  2. | 679 | root | localhost | test | Query | 6 | Opening tables | select * from other_table limit 1 |

唯一的选择似乎就只能是改变文件系统了。例如,换成处理文件删除更有效的XFS文件系统。

EXT3

代码:

  1. mysql> drop table large_table;
  2. Query OK, 0 rows affected (7.44 sec)

的xfs

代码:

  1. mysql> drop table large_table;
  2. Query OK, 0 rows affected (0.29 sec)

一个MySQL的内部操作可能更好一点:可以通过先重命名对应的数据文件,再在没有互斥信号锁的情况下删除物理文件。但是事实上可能没有那么简单,因为实际的删除操作是由存储引擎来完成的,因此不是MySQL的代码能控制的。

这肯定不是一个共同的情况,但是有时候(虽然我们极其不愿)确实可能会让任何人头痛(例如,删除一个老的不再使用的表) 。

这里绍明同学说应该翻译成:这不是一个常见的情况,但是它可能会在最不期望出现的时候成为一个问题(例如 删除没有使用的旧表).


后附:

一个评论回复说:

从一个完全不同的领域的解决办法。

mythtv (电视记录系统)开发者们在ext3系统上删除大型文件时,通过“缓慢删除”功能取得更好的效果。一般来说,电视录音大概1 – 12GB每小时,所以一部电影可以20 + GB大小的文件。如果没有该功能,删除文件操作将锁定ext3整个系统约20-30秒。

“慢删除”只是在后台执行将文件中的块清空的操作。

另一个评论说:

我应该指出,这并不只适用于MyISAM表,对于InnoDB表,在innodb_file_per_table模式下也一样。
我最近刚跟客户做了个spoke,他们几乎无法删掉一个400G的表,因为这个操作阻塞了很长时间。。

更改字符集设置[译文]

更改字符集设置
原文设置:http://www.mysqlperformanceblog.com/2009/03/17/converting-character-sets/

Web世界已经走向UTF8;Drizzle选中它作为默认的字符集。大多网站后端用utf-8来存储文本数据,另外那些用latin1字符集的网也开始将他们的数据库迁移到utf8;google一下”mysql convert charset to utf8″,可以找到大量的网站,每个途径都有些微的不同,又在某些方面都有些不对。我会总结一下这些方法,说明他们为什么不奏效,然后给出一段脚本,大致上可以用来转换一个数据库或是一系列表到目标字标集。

方法一:

ALTER TABLE `t1` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

拿这个数据表作例子,我们可以看到这种方法为啥子行不通呢。

SQL:

1.
mysql> CREATE TABLE `t1` (
2.
-> `c1` text NOT NULL
3.
-> ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
4.
Query OK, 0 rows affected (0.02 sec)
5.

6.
mysql> ALTER TABLE `t1` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;
7.
Query OK, 0 rows affected (0.02 sec)
8.
Records: 0 Duplicates: 0 Warnings: 0
9.

10.
mysql> SHOW CREATE TABLE `t1`G
11.
*************************** 1. row ***************************
12.
TABLE: t1
13.
CREATE TABLE: CREATE TABLE `t1` (
14.
`c1` mediumtext NOT NULL
15.
) ENGINE=MyISAM DEFAULT CHARSET=utf8
16.
1 row IN SET (0.01 sec)


注意这里的c1隐含的从text到mediumtext的转换。这种方法能引起改变的数据类型和没有提示的截断,这从我们的目的上说是不能接受的。

方法二[在这里记录着]:

这种方法在转换之前,把所有的数据都转成了他二进制相似的数据类类型,避免了隐含的类型转换。由于实现方式的限制,他把原来以二进制形式存储的数据列也转成了文本的近似列。另外,这种方式有可能因为二进制数据不能进行全文检索而失败。即使这些解决了,这个过程也因为它过多的在每个表上执行alter语句而不能用在大数据量的数据库上。这些语句包括:
1) Drop FULLTEXT indexes
2) Convert target columns to their binary counterparts
3) Convert the table to the target character set
4) Convert target columns to their original data types
5) Add FULLTEXT indexes back
由于这些语句有时执行一句我们都需要花上n个钟头(我们是不是该庆幸是用小时来计数而不是用天来计数?),这也是不可接受的。

方法三:
导出整个数据库,再导入进去。当然,导入导出时选用正确的server端和client端字符集。
这是一个有三个步骤的过程。我们先导出数据库结构,然后手工编辑把数据字符集修改正确,接出单独导出数据。接下来,创建数据表结构,导入数据。如果你在使用复制(replication),这通常不太可取,因为这样导致可笑的一大堆日志,并引起复制链上所有服务器重新载入数据。
除开方法一之外,这些方法都不必要地麻烦。针对方法一,考虑一下下面这个alter语句:

1.
ALTER TABLE `t1`
2.
DEFAULT CHARSET=utf8,
3.
MODIFY COLUMN `c1` text CHARACTER SET utf8;

这个语句能转换整个表的默认字符集和目标数据表列的字符集,并且保持全文索引不变。对于一个指定的数据表,只需要一句sql语句。一个perl脚本已经写好了,它可以将这个alter table 的操作原子化,您可以从这里下载:

$ wget http://www.pablowe.net/convert_charset

当这个脚本完成后,它会加到launchpad的Percona Tools 中去(也许是maatkit,如果证明是足够有用的话).它的一些不错的特性包括:
1.对字符型外键的恰当处理。(当下还没搞定,不过你可能最好不要使用字符型外键)
2.可以调节这个脚本创建的线程数目。(目前是每个表一个线程).
用法:

Usage:
convert_charset –database=database [options]
Options:
–askpass Prompt for a MySQL password
–charset The target character set to convert to
–collate The target collation to convert to
–database|d The target database
–help|? Display this help and exit
–host|h The target host
–ignore-columns Columns to ignore, useful if you want to
keep the existing charset for a target column
Comma-separated. NO SPACES.
table.column
–ignore-tables A comma-separated list of tables to ignore
–password|p The MySQL password to use
–port The target port
–tables A comma-separated list of tables to convert.
All non-named tables will be ignored
–test Print the ALTER statements that would be executed
without executing them.
–user|u The MySQL user
–version|V Display version information and exit
defaults are:
ATTRIBUTE VALUE
————————– ——————
askpass FALSE
charset utf8
collate No Default Value
database No Default Value
help FALSE
host localhost
ignore-columns No Default Value
ignore-tables No Default Value
password No Default Value
port 3306
tables No Default Value
test FALSE
user Current User
version FALSE