- 浏览: 2542974 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (676)
- linux运维 (157)
- php (65)
- mysql (78)
- nginx (27)
- apche (18)
- framework (6)
- windows (9)
- IDE工具 (23)
- struts2 (7)
- java (13)
- 移动互联网 (14)
- memcache redis (23)
- shell基础/命令/语法 (37)
- shell (50)
- puppet (4)
- C (11)
- python (9)
- 产品经理 (27)
- Sphinx (4)
- svn (12)
- 设计构建 (12)
- 项目管理 (44)
- SEO (1)
- 网站架构 (26)
- 审时度势 (42)
- 网络 (14)
- 激发事业[书&视频] (81)
- 其它 (12)
- 摄影 (8)
- android (21)
最新评论
-
zhongmin2012:
原文的书在哪里
数据库水平切分的实现原理解析---分库,分表,主从,集群,负载均衡器 -
renzhengzhi:
你好,请问个问题,从master同步数据到slave的时候,s ...
数据库水平切分的实现原理解析---分库,分表,主从,集群,负载均衡器 -
ibc789:
你好,看了你的文章,我想请教个问题, 我在用 redis的时候 ...
redis 的两种持久化方式及原理 -
iijjll:
写得非常好
数据库水平切分的实现原理解析---分库,分表,主从,集群,负载均衡器 -
iijjll:
写得非常好
数据库水平切分的实现原理解析---分库,分表,主从,集群,负载均衡器
http://www.myext.cn/Article/921.html
概要
简介
先看看下面这个过程:
- 我们从未手动开启过PHP的相关进程,它是随着Apache的启动而运行的;
- PHP通过mod_php 5.so模块和Apache相连(具体说来是SAPI,即服务器应用程序编程接口);
- PHP总共有三个模块:内核、Zend引擎、以及扩展层;
- PHP内核用来处理请求、文件流、错误处理等相关操作;
- Zend引擎(ZE)用以将源文件转换成机器语言,然后在虚拟机上运行它;
- 扩展层是一组函数、类库和流,PHP使用它们来执行一些特定的操作。比如,我们需要mysql扩展来连接MySQL数据库;
- 当ZE执行程序时可能会需要连接若干扩展,这时ZE将控制权交给扩展,等处理完特定任务后再返还;
- 最后,ZE将程序运行结果返回给PHP内核,它再将结果传送给SAPI层,最终输出到浏览器上。
深入探讨
等等,没有这么简单。以上过程只是个简略版,让我们再深入挖掘一下,看看幕后还发生了些什么。
- Apache启动后,PHP解释程序也随之启动;
- PHP的启动过程有两步;
- 第一步是初始化一些环境变量,这将在整个SAPI生命周期中发生作用;
- 第二步是生成只针对当前请求的一些变量设置。
PHP启动第一步
不清楚什么第一第二步是什么?别担心,我们接下来详细讨论一下。让我们先看看第一步,也是最主要的一步。要记住的是,第一步的操作在任何请求到达之前就发生了。
- 启动Apache后,PHP解释程序也随之启动;
- PHP调用各个扩展的MINIT方法,从而使这些扩展切换到可用状态。看看php .ini文件里打开了哪些扩展吧;
- MINIT的意思是“模块初始化”。各个模块都定义了一组函数、类库等用以处理其他请求。
一个典型的MINIT方法如下:
PHP_MINIT_FUNCTION(extension_name){
/* Initialize functions, classes etc */
}
PHP启动第二步
- 当一个页面请求发生时,SAPI层将控制权交给PHP层。于是PHP设置了用于回复本次请求所需的环境变量。同时,它还建立一个变量表,用来存放执行过程中产生的变量名和值。
- PHP调用各个模块的RINIT方法,即“请求初始化”。一个经典的例子是Session模块的RINIT,如果在php .ini中启用了Session模块,那在调用该模块的RINIT时就会初始化$_SESSION变量,并将相关内容读入;
- RINIT方法可以看作是一个准备过程,在程序执行之间就会自动启动。
一个典型的RINIT方法如下:
PHP_RINIT_FUNCTION(extension_name) {
/* Initialize session variables, pre-populate variables, redefine global variables etc */
}
PHP关闭第一步
如同PHP启动一样,PHP的关闭也分两步:
- 一旦页面执行完毕(无论是执行到了文件末尾还是用exit或die函数中止),PHP就会启动清理程序。它会按顺序调用各个模块的RSHUTDOWN方法。
- RSHUTDOWN用以清除程序运行时产生的符号表,也就是对每个变量调用unset函数。
一个典型的RSHUTDOWN方法如下:
PHP_RSHUTDOWN_FUNCTION(extension_name) {
/* Do memory management, unset all variables used in the last PHP call etc */
}
PHP关闭第二步
最后,所有的请求都已处理完毕,SAPI也准备关闭了,PHP开始执行第二步:
- PHP调用每个扩展的MSHUTDOWN方法,这是各个模块最后一次释放内存的机会。
一个典型的RSHUTDOWN方法如下:
PHP_MSHUTDOWN_FUNCTION(extension_name) {
/* Free handlers and persistent memory etc */
}
这样,整个PHP生命周期就结束了。要注意的是,只有在服务器没有请求的情况下才会执行“启动第一步”和“关闭第二步”。
一、开篇
在开始这个专题之前,先说一点题外话。大多数人学习编程语言的时候,首先关注的是这种语言的语法及其常用函数。我学习 C,Java,Php 等 语言就是按照这样的方式开始的。一般情况下,这个阶段需要一个月左右的时间就会完全掌握,并能基本熟练地使用。对于已有经验的同学,可能时间更短。其实各 种语言的语法和常用函数都差别不大,有很多相通的地方。如果您在学习一种编程语言的时候,拿一些真正的项目任务作为实践,效果更佳,实践远胜于理论。
我们在掌握了一门编程语言之后,又会向两个方向发展:一个方向是向上延伸,从事系统框架结构的探索;另一方向是向下延伸,从事系统底层方面的研究,我大体画了一下这个学习演变过程的示意图。
注:虽然我的形象一直用着“高高手”,但我只是个菜鸟,如有雷同,纯属巧合,欢迎善意拍砖。
php 的语法非常简单,正是它的简单性,使它成为了当前互联网第一编程语言。你不需要具备很多的知识就能上手,比如:你学习 C 语言,就必须非常了解各个变量如何定义,指针如何操作,内存如何创建销毁等等。再比如:你学习 Java 语言,就必须具有面向对象 (OO) 的基础 , 就必须清楚是什么时候需要封装,什么时候需要继承,什么时候需要多态,要做项目,怎么还得懂点 SSH 。 Php 的大部分使用者可能根本就没这么多讲究,有的人喜欢面向过程,那你就用面向过程的方式来写代码;有的人喜欢面向对象,那你就用面向对象的方式写代码。 Php 的产生缘于互联网,目前也是互联网Web2.0第一编程语言。满足用户需求永远是第一位的,可维护性暂且可以放在第二 位。我们通常说 Web 应用永远是 β 版的,计划远没有变化快。
我们公司里有很多 phper ,我曾经问过他们:“ php 程序到底是如何被执行的?”,多数人似乎很难说得清楚。这种情况,其实并不奇怪,我曾经拿类似的问题问过 Javaer , Javaer 的回答也是如此。有的同学会问:“研究这样的问题有没有实际意义呢?”我说:“有!”。理解系统的底层,有助于你写出高效健壮的代码,你会更清楚程序的代码到底该怎么去写。另外,如果你有志去做 php 扩展,那就更不必说,责无旁贷。
要回答以上问题,我觉得最好的办法是阅读一下 php 的源码,从“根”上解决。近来我找了点时间,粗读了一遍,愿意与各位共享。
关于 php 的底层工作原理,一定绕不开 webserver ,象 apache , lighttpd , nginx , iis 等。我这里就选择 apache为例吧 。以下内容将结合 apache 的源码、工作原理和扩展来逐步切入 php 的解析过程。
二、 Apache 运行机制剖析
l B/S 交互过程
浏览器(Browser) 和服务器(Web Server) 的交互过程:
1、 浏览器 向服务器 发出 HTTP 请求 (Request) 。
2、 服务器收到浏览器的请求数据,经过 分析处理,向浏览器输出响应数据( Response )。
3、 浏览器 收到服务器的响应数据,经过分析处理,将最终结果显示在浏览器中。
下图是一份浏览器请求数据和服务器响应数据的快照:
关于浏览器和服务器数据交互过程非常简单,很容易理解。我想从事 Web 开发的人员都很清楚,在此不再赘述,仅供参考。
l Apache 概述
Apache 是目前世界上使用最为广泛的一种 Web Server ,它以跨平台、高效和稳定而闻名。按照去年官方统计的数据, Apache 服务器的装机量占该市场 60% 以上的份额。尤其是在 X ( Unix/Linux )平台上,Apache是 最常见的选择。其它的 Web Server 产品,比如 IIS, 只能运行在 Windows 平台上,是基于微软 .Net 架构技术 的不二选择。
Apache并不是没有缺点,它 最为诟病的一点就是变得越来越重,被普遍认为是重量级的 WebServer。 所以,近年来又涌现出了很多轻量级的替代产品,比如 lighttpd,nginx等等 ,这些WebServer的优点是运行效率很高,但缺点也很明显,成熟度往往要低于Apache,通常只能用于某些特定场合,。
l Apache 组件逻辑图
Apache 是基于模块化设计的,总体上看起来代码的可读性高于php的代码,它的核心代码并不多,大多数的功能都被分散到各个模块中,各个模块在系统启动的时候按需载入。你如果想要阅读 Apache的 源代码,建议你直接从main .c文件 读起,系统最主要的处理逻辑都包含在里面。 MPM ( Multi -Processing Modules ,多重处理模块)是 Apache 的核心组件之一, Apache 通过 MPM来 使用操作系统的资源,对进程和线程池进行管理。Apache为了能够获得最好的运行性能, 针对不同的平台 (Unix/Linux 、 Window)做了优化,为不同的平台提供了 不同的 MPM,用户可以根据实际情况进行选择, 其中最常使用的MPM有 prefork 和 worker 两种。至于您的服务器正以哪种方式运行,取决于安装 Apache过程中 指定的MPM编译 参数,在 X 系统上默认的编译参数为 prefork 。由于大多数的 Unix 都不支持真正的线程,所以采用了预派生子进程 (prefork) 方式,象Windows或者Solaris这些支持线程的平台,基于多进程多线程混合的worker 模式 是一种不错的选择。对此感兴趣的同学可以阅读有关资料,此处不再多讲。Apache中还有一个重要的组件就是APR ( Apache portable Runtime Library ),即 Apache 可移植运行库,它是一个对操作系统调用的抽象库,用来实现 Apache 内部组件对操作系统的使用,提高系统的可移植性。 Apache 对于 php 的解析,就是通过众多Module中的php Module 来完成的。
Apache 的逻辑构成以及与操作系统的关系
l Apache 的生命周期
这一节的内容会与 php 模块的载入有关,您可以略微关注一下。以下是 Apache 的生命周期( prefork 模式)示意图。
l Apache 的生命周期
这一节的内容将会阐述 php 模块的载入过程,请参考 Apache 的生命周期示意图( prefork 模式下)。
Apache 的运行分为启动阶段和运行阶段。
1. 启动阶段
在启动阶段, Apache 主要进行配置文件解析 ( 例如 http.conf 以及 Include 指令设定的配置文件等 ) 、模块加载 ( 例如 mod_php.so,mod_perl.so 等 ) 和系统资源初始化(例如日志文件、共享内存段等)工作。
在这个阶段, Apache 为了获得系统资源最大的使用权限,将以特权用户 root ( X 系统)或超级管理员 administrator(Windows 系统 ) 完成启动。
Apache 和“ php 处理机”的装配过程就是在这个阶段完成的。
“ php 处理机”就是负责解释和执行你的 php 代码的系统模块。这个名字是我特意创造的,目的是为了帮助你理解本节的内容,后面的章节还会给出更专业的名称。
你单独做过 php 的安装配置吗?
如果你做过类似的工作,下面的内容很容易理解;如果你没有做过,可以尝试安装一下,有助于加深你的理解。不过,我的文章向来深入浅出,我会尽量把这个过程讲得更浅显一些。其实 php 的安装非常简单,如果你很感兴趣的话,可以到网上随便搜一篇安装指南,按步骤照做就可以了。
把 php 最终集成到 Apache 系统中,还需要对 Apache 进行一些必要的设置。这里,我们就以 php 的 mod_php5 SAPI 运行模式为例进行讲解,至于 SAPI 这个概念后面我们还会详细讲解。
假定我们安装的版本是 Apache2 和 Php5 ,那么需要编辑 Apache 的主配置文件 http.conf ,在其中加入下面的几行内容:
Unix/Linux 环境下 :
LoadModule php5_module modules/mod_php5.so
AddType application/x-httpd-php .php
注:其中 modules/mod_php5.so 是 X 系统环境下 mod_php5.so 文件的安装位置。
Windows 环境下:
LoadModule php5_module d:/php/php5apache2.dll
AddType application/x-httpd-php .php
注:其中 d:/php/php5apache2.dll 是在 Windows 环境下 php5apache2.dll 文件的安装位置。
这两项配置就是告诉 Apache Server ,以后收到的 Url 用户请求,凡是以 php 作为后缀,就需要调用 php5_module 模块( mod_php5.so/ php5apache2.dll )进行处理。
这个过程可以参考以下的示意图:
Apache 启动阶段的源码包含在 server/main.c 中,我整理了一下源码中的对应关系:
不熟悉 unix/linux 的同学可能会问 so 文件( mod_php5.so) 是个什么样的文件 ?
unix/linux 下 ,so 后缀文件是一个 DSO 文件, DSO 与 windows 系统下的 dll 是等价概念,都是把一堆函数封装在一个二进制文件中。调用它们的进程把它们装入内存后,会将其映射到自己的地址空间。
DSO 全称为 Dynamic Shared Object ,即动态共享对象。 DLL 全称为 Dynamic Link Library 即动态链接库。
Apache 服务器的体系结构的最大特点,就是高度模块化。如果你为了追求处理效率,可以把这些 dso 模块在 apache 编译的时候静态链入,这样会提高 Apache 5% 左右的处理性能。
2. 运行阶段
在运行阶段, Apache 主要工作是处理用户的服务请求。
在这个阶段, Apache 放弃特权用户级别,使用普通权限,这主要是基于安全性的考虑,防止由于代码的缺陷引起的安全漏洞,象微软的 IIS 就曾遭受“红色代码( Code Red )”和“尼姆达( Nimda )”等恶意代码的溢出攻击。
2、运行阶段
2.1 运行阶段概述
在运行阶段,Apache主要工作是处理用户的服务请求。
在这个阶段,Apache放弃特权用户级别,使用普通权限,这主要是基于安全性的考虑,防止由于代码的缺陷引起的安全漏洞。象微软的IIS就曾遭受“红色代码(Code Red)”和“尼姆达(Nimda)”等恶意代码的溢出攻击。
2.2 运行阶段流程
Apache将请求处理循环分为11个阶段,依次是:Post-Read-Request,URI Translation,Header
Parsing,Access Control,Authentication,Authorization,MIME Type
Checking,FixUp,Response,Logging,CleanUp。
Apache Hook机制
Apache 的Hook机制是指:Apache 允许模块(包括内部模块和外部模块,例如mod_php5.so,mod_perl.so等)将自定义的函数注入到请求处理循环中。换句话说,模块可以在 Apache的任何一个处理阶段中挂接(Hook)上自己的处理函数,从而参与Apache的请求处理过程。
mod_php5.so/ php5apache2.dll就是将所包含的自定义函数,通过Hook机制注入到Apache中,在Apache处理流程的各个阶段负责处理php请求。
关于Hook机制在Windows系统开发也经常遇到,在Windows开发既有系统级的钩子,又有应用级的钩子。常见的翻译软件(例如金山词霸等等)的 屏幕取词功能,大多数是通过安装系统级钩子函数完成的,将自定义函数替换gdi32.dll中的屏幕输出的绘制函数。
Apache请求处理循环详解
Apache请求处理循环的11个阶段都做了哪些事情呢?
1、Post-Read-Request阶段
在正常请求处理流程中,这是模块可以插入钩子的第一个阶段。对于那些想很早进入处理请求的模块来说,这个阶段可以被利用。
2、URI Translation阶段
Apache在本阶段的主要工作:将请求的URL映射到本地文件系统。模块可以在这阶段插入钩子,执行自己的映射逻辑。mod_alias就是利用这个阶段工作的。
3、Header Parsing阶段
Apache在本阶段的主要工作:检查请求的头部。由于模块可以在请求处理流程的任何一个点上执行检查请求头部的任务,因此这个钩子很少被使用。mod_setenvif就是利用这个阶段工作的。
4、Access Control阶段
Apache在本阶段的主要工作:根据配置文件检查是否允许访问请求的资源。Apache的标准逻辑实现了允许和拒绝指令。mod_authz_host就是利用这个阶段工作的。
5、Authentication阶段
Apache在本阶段的主要工作:按照配置文件设定的策略对用户进行认证,并设定用户名区域。模块可以在这阶段插入钩子,实现一个认证方法。
6、Authorization阶段
Apache在本阶段的主要工作:根据配置文件检查是否允许认证过的用户执行请求的操作。模块可以在这阶段插入钩子,实现一个用户权限管理的方法。
7、MIME Type Checking阶段
Apache在本阶段的主要工作:根据请求资源的MIME类型的相关规则,判定将要使用的内容处理函数。标准模块mod_negotiation和mod_mime实现了这个钩子。
8、FixUp阶段
这是一个通用的阶段,允许模块在内容生成器之前,运行任何必要的处理流程。和Post_Read_Request类似,这是一个能够捕获任何信息的钩子,也是最常使用的钩子。
9、Response阶段
Apache在本阶段的主要工作:生成返回客户端的内容,负责给客户端发送一个恰当的回复。这个阶段是整个处理流程的核心部分。
10、Logging阶段
Apache在本阶段的主要工作:在回复已经发送给客户端之后记录事务。模块可能修改或者替换Apache的标准日志记录。
11、CleanUp阶段
Apache在本阶段的主要工作:清理本次请求事务处理完成之后遗留的环境,比如文件、目录的处理或者Socket的关闭等等,这是Apache一次请求处理的最后一个阶段。
模块的注入Apache的
过程可以参考源码中server/core.c文件:
mod_php5.so/ php5apache2.dll注入到Apache的函数中,最重要的就是Response阶段的处理函数。
发表评论
-
设置sudo为不需要密码
2015-04-17 09:04 10516有时候我们只需要执 ... -
haproxy 安装配置和负载实例
2015-03-27 11:49 11535一、环境说明实验环境 OS CentOS5.4 192.1 ... -
/dev/mapper/VolGroup00-LogVol00 100% 如何处理
2015-03-03 10:51 8219服务器磁盘跑满了, 命令查看 如下 [root@lo ... -
Tsar开源:淘宝内部大量使用的系统监控工具
2014-08-07 09:51 973Tsar是淘宝的一个用来收集服务器系统和应用信息的采集报告 ... -
wamp 升级php apache mysql
2014-02-18 14:30 1193wamp对于日常开发来说会增添非常大的方便 但是对于集成 ... -
Linux运维常用命令 (转载)
2013-01-31 10:23 25291 删除0字节文件find-type f - ... -
linux恢复 rm -rf 删除的文件:extundelete
2013-01-24 15:47 8916http://blog.csdn.net/pang6013 ... -
网站排障分析常用的命令
2013-01-21 18:17 1400------------------------------- ... -
迁移vmware服务器后Device eth0 does not seem to be present
2013-01-21 10:58 2251用VMware 安装 linux 6.0 ... -
LoadRunner如何监控Linux系统资源 : rpc.rstatd
2012-12-17 14:49 10302一 简述:LoadRunner监控Linux资源时弹出如下错误 ... -
僵尸Z进程和D进程
2012-12-10 16:47 13154-------------- 1 关于ZOMBIE进 ... -
Unix操作系统硬链接与符号链接的区别
2012-12-10 16:08 2024Unix操作系统有很多值得 ... -
nagios配置参数详解
2012-12-04 14:12 9448# Nagios return codes#定 ... -
nagios自定义监控nginx php和ip_conn
2012-12-03 17:57 3170自定义ip_conn.sh :http://zhume ... -
【汇总】shell show收藏
2012-11-29 14:03 1288================== shell从文本取对应的 ... -
Kickstart+PXE+DHCP+TFTP+NFS自动安装Centos5
2012-11-29 11:34 1606http://5ydycm.blog.51cto.com/11 ... -
haproxy+keepalived高可用负载均衡(七层)
2012-11-29 10:36 4010HAproxy是一款基于TCP( ... -
LVS+Keepalived
2012-11-29 10:10 1738http://www.linuxvirtualserver.o ... -
haproxy & LVS*(keepalived和heartbeat) & ng的比较
2012-11-29 10:04 7600http://network.51cto.com/art/ ... -
运维架构师-并不遥远的彼岸
2012-11-28 17:45 1737在百度里搜索运维架构师,你会发现招聘的职位还不少并且月薪、年 ...
相关推荐
【探究PHP底层运行机制】 PHP是一种广泛使用的开源脚本语言,尤其在Web开发领域中扮演着重要角色。本文将深入探讨PHP如何与服务器交互并执行代码。PHP的运行机制涉及多个层次,包括SAPI(Server Application ...
本文从互联网支付时代的背景出发,分析了当前收银审核运行机制存在的问题,并提出了相应的有效措施,以期为企业的稳定发展提供参考。 首先,互联网支付的普及带来了诸多便利,但它也改变了客户的支付习惯,并对企业...
因此,探究高校后勤管理体制与运行机制的现状、问题及改革方向,对于推动高校后勤管理的发展具有重要意义。 高校后勤管理的现状与问题 当前,我国高校后勤管理面临的主要挑战有以下几点:一是管理队伍建设步伐缓慢...
总之,基于CAS理论的精准医疗运行机制探究有助于我们理解并改进当前面临的挑战,为构建更加高效、公正且科学的精准医疗服务体系提供理论指导。未来的研究应进一步细化这些机制,结合具体实践案例,探索更适应我国...
在高等教育领域,考试管理体制和运行机制的改革一直是教育者和学者们讨论的焦点。随着中国高等教育教学改革的不断深化,传统的考试制度已不能满足现代教育的需求,特别是在培养学生创新能力和实践能力方面显得...
基于现代学徒制的校企合作运行机制是这种模式的核心,它强调学校与企业之间的紧密联系,共同参与人才培养的全过程。 1. 现代学徒制校企合作运行机制的基本特点: (1)全方位合作:在现代学徒制下,学校和企业共同...
因此,探究和完善这一机制的有效手段,对于确保互联网支付的健康发展和用户资金安全具有重要意义。 一、专业人才培养是基础 面对互联网支付的普及,首先需要重视的是专业收银审核人才的培养。这些人才不仅要掌握...
鉴于当前的种种问题,如服务问题、技术问题、网络安全问题等,新时期创新完善收银审核运行机制的策略已是势在必行,这对企业的资金安全问题和未来发展具有重要的现实意义与经济意义。 总之,在互联网支付时代,企业...
这种模式下的校企合作运行机制具有显著的特点,包括全方位合作、持续性和深入性,以及企业承担较大的育人责任和成本。 1. 全方位合作:在现代学徒制中,企业和学校不再是简单的供需关系,而是共同参与学生的培养...
企业财务管理转型探究.doc
2021年探究土地储备新机制服务地方经济战略社会发展.docx
我们通过首先以一个循环的阶次显式和解析地评估O(N)λϕ4标量场理论的振幅比的循环量子校正来探究两尺度因子普遍性假设,其中旋转对称性在三个不同且独立的条件下破裂 精确处理旋转对称破坏机制的方法。...
Handler使用简单功能强大,常被用作线程间传递消息的组件,而且还可以用于跨进程。 消息机制背后有包括Looper ,MessageQueue管理和分发消息的实现,...这里从Java层开始深入探究下Handler和消息机制背后实现的原理
大数据下教体局财务会计向管理会计转型探究
人工智能背景下证券公司的财务管理转型探究
本文将深入探究梯级扬水泵站自动化智能控制系统的运行机制,并分析其在实际应用中的效果。 首先,我们不妨从变压器线圈套装用混联机械臂的设计开始谈起,这是一种智能系统在工业生产中的典型应用。在变压器线圈的...
财务信息化背景下财务会计向管理会计转型探究.docx
【标题】"06.03-转型时期报刊企业管理创新特征及其动力机制探究"主要探讨的是在媒体转型的关键阶段,报刊企业如何通过管理创新来适应市场变化,提升竞争力。在这个过程中,企业管理创新的特征和推动这些创新的动力...
最后,大数据背景下的企业会计核算转型需要创建有效的反馈处理机制,在试运行期间收集数据并进行科学的分析,以确保转型工作的有效性和可持续性。同时,企业还应注重分析评价需求的挖掘和整合,以及如何激发管理需求...
行业资料-交通装置-一种探究公交车运行时间可靠性影响因素的方法.zip