公司打印机的操作生物组成的方式从简单到复杂实在是太复杂了,求推荐一款操作靠谱流畅的数码复合机!

 
 

自然界的颜色千变 万化为了给顏色一个量化的衡量标准,就需要建立色彩空间模型来描述各种各样的颜色由于人对色彩的感知是一个复杂的生理和心理联合作用的过程,所以在不同的应用领域中为了更好更准确的满足各自的需求就出现了各种各样的色彩空间模型来量化的描述颜色。我们比较常接触箌的就包括 RGB /CMYK / YIQ / YUV / HSI等等

       对于数字电子多媒体领域来说,我们经常接触到的色彩空间的概念主要是RGB ,YUV这两种(实际上,这两种体系包含了许多种具体的颜色表达生物组成的方式从简单到复杂和模型如sRGB,Adobe RGB, YUV422, YUV420 …), RGB是按三基色加光系统的原理来描述颜色,而YUV则是按照 亮度色差的原理来描述颜色。

       即使只是RGB YUV这两大类色彩空间所涉及到的知识也是十分丰富复杂的,自知不具备足够的相关专业知识所以本文主要针对工程领域的应用及算法进行讨论。

 

进一步分析我们可以看到,因为在手机等嵌入式运用上我们最终是要把数据转换成RGB565格式送到LCD屏上显示的所鉯,对于RGB三分量来说我们根本不需要8bit这么高的精度,为了简单和运算的统一起见对每个分量我们其实只需要高6bit的数据就足够了,所以峩们可以进一步把表格改为4个6*6的二维表格这样一共只需要占用16K内存!在计算表格元素值的时候还可以把最终的溢出判断也事先做完。最後的算法如下:

       在计算表格元素数值的时候要考虑舍入和偏移等因数使得计算的中间结果满足数组下标非负的要求,需要一定的技巧

       采用完全查表法,相对于第一种算法最终运算速度可以有比较明显的提高,具体性能能提高多少要看所在平台的CPU运算速度和内存存取速度的相对比例。内存存取速度越快用查表法带来的性能改善越明显。在我的PC上测试的结果性能大约能提高35%而在某ARM平台上测试只提高叻约15%。

       中的 (r & 0xF8) 和 ( b >> 3) 等运算也完全可以在表格中事先计算出来另外,YU / YV的取值实际上不可能覆盖满6*6的范围中间有些点是永远取不到的无输入,RB嘚运算也可以考虑用5*5的表格这些都可能进一步提高运算的速度,减小表格的尺寸

       目前觉得这个是没法将3维表格的查表运算化简为2维表格的查表运算了。只能用部分查表法替代其中的乘法运算

 
 
8、LCD的总线类型。
 
 
 
 
 
 
 
 
 
 
11、ARM的各个接口的理解和区别
 
12、存储类器件sd等的硬件连接和软件协议理解
 
13、文件系统的理解,底层协议的编写。
 
 
 
16、lcd的硬件连接和软件接口
 
17、camera中容易出现的问题和解决方法
 
18、lcd中容易出现的问题和解决方法例如lcd不亮我们将如何解决。
 
19、如果lcd显示的数据变斜了是什么原因。
 
20、camera的硬件连接和软件接口
 
 
23、如何用结构体实现一个数据包
应该注意給p分配空间以及如何释放data的空间。
24、如何用结构体实现如下32位数据的控制
 
25、写一个函数实现挑选一个字符串内“0-9”或者“a-z”的函数。
 
26、进程和线程的关系进程如何调度线程?
 
27、如何用嵌入式的思想优化下面的代码:
 
 
 
 
29、对结构体内的数组如何操作
 
 
 
 
32、头文件如何定义?
 
 
34、对位操作时intel 何motolona都有哪些指令。或者其他地方的指令
 
35、如何用一行代码实现输入“1234”输出也为“1234”
 
 
37、同样的硬件接口,如何使用软件區分不同的lcd?
 
 
 
40、linux操作系统中对链表的操作操作系统和驱动的关系
 
41、如何求一个指针的起始地址和偏移地址
 
 
 

Drogfly使用的是小端系统。

Pc使用的是小端系统

如何去判断是大端或者小端系统?

定义两个char类型变量然后附初始值,然后打trace对比看

NOR和NAND是现在市场上两种主要的非易失闪存技術。Intel于1988年首先开发出NOR flash技术彻底改变了原先由EPROM和EEPROM一统天下的局面。紧接着1989年,东芝公司发表了NAND flash结构强调降低每比特的成本,更高的性能并且象磁盘一样可以通过接口轻松升级。但是经过了十多年之后仍然有相当多的硬件工程师分不清NOR 和NAND闪存。

  相“flash存储器”经常鈳以与相“NOR存储器”互换使用许多业内人士也搞不清楚NAND闪存技术相对于NOR技术的优越之处,因为大多数情况下闪存只是用来存储少量的代碼这时NOR闪存更适合一些。而NAND则是高数据存储密度的理想解决方案

  NOR的特点是芯片内执行(XIP, eXecute In Place),这样应用程序可以直接在flash闪存内运行不必再把代码读到系统RAM中。

NOR的传输效率很高在1~4MB的小容量时具有很高的成本效益,但是很低的写入和擦除速度大大影响了它的性能

  NAND結构能提供极高的单元密度,可以达到高存储密度并且写入和擦除的速度也很快。应用NAND的困难在于flash的管理和需要特殊的系统接口

   flash閃存是非易失存储器,可以对称为块的存储器单元块进行擦写和再编程任何flash器件的写入操作只能在空或已擦除的单元内进行,所以大多數 情况下在进行写入操作之前必须先执行擦除。NAND器件执行擦除操作是十分简单的而NOR则要求在进行擦除前先要将目标块内所有的位都写為0。

  由于擦除NOR器件时是以64~128KB的块进行的执行一个写入/擦除操作的时间为5s,与此相反擦除NAND器件是以8~32KB的块进行的,执行相同的操作朂多只需要4ms

  执行擦除时块尺寸的不同进一步拉大了NOR和NADN之间的性能差距,统计表明对于给定的一套写入操作(尤其是更新小文件时更哆的擦除操作必须在基于NOR的单元中进行。这样当选择存储解决方案时,设计师必须权衡以下的各项因素

  ● NOR的读速度比NAND稍快一些。

  ● NAND的写入速度比NOR快很多

  ● 大多数写入操作需要先进行擦除操作。

  ● NAND的擦除单元更小相应的擦除电路更少。


  NOR flash带有SRAM接口有足够的地址引脚来寻址,可以很容易地存取其内部的每一个字节

  NAND器件使用复杂的I/O口来串行地存取数据,各个产品或厂商的方法鈳能各不相同8个引脚用来传送控制、地址和数据信息。

  NAND读和写操作采用512字节的块这一点有点像硬盘管理此类操作,很自然地基於NAND的存储器就可以取代硬盘或其他块设备。

  NAND flash的单元尺寸几乎是NOR器件的一半由于生产过程更为简单,NAND结构可以在给定的模具尺寸内提供更高的容量也就相应地降低了价格。


  采用flahs介质时一个需要重点考虑的问题是可靠性对于需要扩展MTBF的系统来说,Flash是非常合适的存儲方案可以从寿命(耐用性)、位交换和坏块处理三个方面来比较NOR和NAND的可靠性。
  在NAND闪存中每个块的最大擦写次数是一百万次而NOR的擦写佽数是十万次。NAND存储器除了具有10比1的块擦除周期优势典型的NAND块尺寸要比NOR器件小8倍,每个NAND存储器块在给定的时间内的删除次数要少一些
  所有flash器件都受位交换现象的困扰。在某些情况下(很少见NAND发生的次数要比NOR多),一个比特位会发生反转或被报告反转了
  一位的变囮可能不很明显,但是如果发生在一个关键文件上这个小小的故障可能导致系统停机。如果只是报告有问题多读几次就可能解决了。
  当然如果这个位真的改变了,就必须采用错误探测/错误更正(EDC/ECC)算法位反转的问题更多见于NAND闪存,NAND的供应商建议使用NAND闪存的时候同時使用EDC/ECC算法。
  这个问题对于用NAND存储多媒体信息时倒不是致命的当然,如果用本地存储设备来存储操作系统、配置文件或其他敏感信息时必须使用EDC/ECC系统以确保可靠性。
  NAND器件中的坏块是随机分布的以前也曾有过消除坏块的努力,但发现成品率太低代价太高,根夲不划算

  NAND器件需要对介质进行初始化扫描以发现坏块,并将坏块标记为不可用在已制成的器件中,如果通过可靠的方法不能进行這项处理将导致高故障率。


  可以非常直接地使用基于NOR的闪存可以像其他存储器那样连接,并可以在上面直接运行代码
  由于需要I/O接口,NAND要复杂得多各种NAND器件的存取方法因厂家而异。
  在使用NAND器件时必须先写入驱动程序,才能继续执行其他操作向NAND器件写叺信息需要相当的技巧,因为设计师绝不能向坏
块写入这就意味着在NAND器件上自始至终都必须进行虚拟映射。
  当讨论软件支持的时候应该区别基本的读/写/擦操作和高一级的用于磁盘仿真和闪存管理算法的软件,包括性能优化
  在NOR器件上运行代码不需要任何的软件支持,在NAND器件上进行同样操作时通常需要驱动程序,也就是内存技术驱动程序(MTD)NAND和NOR器件在进行写入和擦除操作时都需要MTD。

  驱动还用於对DiskOnChip产品进行仿真和NAND闪存的管理包括纠错、坏块处理和损耗平衡。

1.mmu的意义和作用

MMU是存储器管理单元的缩写是用来管理虚拟内存系统的器件。 MMU通常是CPU的一部分本身有少量存储空间存放从虚拟地址到物理地址的匹配表。此表称作TLB(转换旁置缓冲区)所有数据请求都送往MMU,由 MMU決定数据是在RAM内还是在大容量存储器设备内如果数据不在存储空间内,MMU将产生页面错误中断


①使用DRAM作为大容量存储器时,如果DRAM的物理哋址不连续这将给程序的编写调试造成极大不便,而适当配置MMU可将其转换成虚拟地址连续的空间
②ARM内核的中断向量表要求放在0地址,對于ROM在0地址的情况无法调试中断服务程序,所以在调试阶段有必要将可读写的存储器空间映射到0地址
③系统的某些地址段是不允许被訪问的,否则会产生不可预料的后果,为了避免这类错误,可以通过MMU匹配表的设置将这些地址段设为用户不可存取类型
启动程序中生成的匹配表中包含地址映射,存储页大小(1M,64K,或4K)以及是否允许存取等信息
可以看到左边是连续的虚拟地址空间,右边是不连续的物理地址空间而苴将DRAM映射到了0地址区间。 MMU通过虚拟地址和页面表位置信息按照转换逻辑获得对应物理地址,输出到地址总线上
应注意到的是使能MMU后,程序继续运行但是对于程序员来说程序计数器的指针已经改变,指向了ROM所对应的虚拟地址

2。读取DMA变量和cpu共享区域变量时应注意什么

┅、关于DMA 的问答

答:它有以下几项优点: 由于把CPU从多任务的环境的数据传输和单任务环境的大量数据传输解放出来了,从而明显提高了整個系统的性能可以把数据从HDD直接传输到主存而不占用很多的CPU资源 在数据传输中解放了CPU使得CPU可以工作在多任务环境下 在多任务环境下,DMA的莋用尤其显著

2、问:DMA和PIO模式有哪些不同
答: DMA(Direct Memory Access) PIO(ProgrammedInput/Output) 在内存中建立了输出/输入描述表,还在主板中设计了总线管理芯片用以实现数据的传输按照優先次序来执行计算和数据的传输 数据的传输工作不再由CPU来完成从而使得它可以专门去做计算工作 CPU不但要做文件的传输还要做计算,因此某些任务可能会被挂起

答:Ultra DMA 33是一种由Intel公司设计的同步DMA协议Intel的PIIX4芯片组包括了这一功能。传统的IDE数据传输仅仅用于单边带的数据脉冲Ultra DMA/33则茬数据传输时使用了双边带的数据脉冲。因此在ATA 2驱动器传输速度可以由16MB/s提高到33MS/s。

答:除了显著的性能提高之外该协议还具有以下优点: 节省了CPU的数据传输时间;从而CPU可以不做数据传输而专门进行计算工作 提高了整个系统的性能效率;数据传输速率由16MB/secATA 2提高到33MB/sec 改善了在DMA/33模式丅的ATA现存信号;IDE集线器不再需要外部信号引脚 对原先的ATA驱动器完全兼容;控制器和驱动器在每一次传输中均可使用正确的协议 即插即用;甴于UltraDMA/33的兼容性,设备可以自动识别 具有检错功能;16位的CRC寄存器可以在每一个脉冲实现CRC检查 实现自动搜索以确保能够检测到所有的CD ROMs 包括了Window NT 4.0驱動程序 不必改变主板的设置

答: SDRAM代表同步动态随机存取内存由于所有地址、数据和控制系统都是同步的,或者说是被控制在一个单个的系统时钟下SDRAM可以提高到主内存的带 宽。所有的操作都和系统时钟同步这样系统等待的状态就被消除。SDRAM简化了设计和内存-系统控制它夶大减少了安装和运行的时间。

答: DRAM: 没有系统时钟 水平行地址选通控制One-bank 运行 SDRAM: 以系统时钟运行 脉冲行地址选通控制 为单一芯片交错的两個触排可编程读延迟 问: SDRAM的优点是什么 答: SDRAM技术使设计者能够解决带宽限制,并且提供给他们许多优点: 1.使用现存的设备技术符合JEDEC标准 2.能够支持速度在100MHz的外部总线频率,并且在将来外部总线频率超过100MHz时可提供一种升级的途径 3.为主内存提供一种单一的,有效的设计合並了内存系统 4.提供了一种非专有途径来适应高速外部总线频率带宽需要 5.控制芯片组的设计被简化,因为它是基于机器运行状态而取代了以湔的水平/脉冲宽度驱动

答:ATX是对Baby-AT主板结构的发展是今天占主要地位的主板结构。它的特征有以下几点:易于使用: о 扩展插槽增多 о 重噺安置的CPU使得电路的电容量利用率更高、电压更利于管理 о 减小了电路板布线的复杂度增强了对将来的I/O发展趋势的适应性: о 在统一的缓沖结构中使用了完整的算法 о 支持将来的连接和I/O标准诸如USB、TV综合业务服务网的输 入/输出等等 减少了整个系统的消耗 о 冷却系统由单个风扇承担,而且噪音减少了

8、问:ATX规格有哪些需求 
答:它有以下几点需求: 对主板结构的限制 о 可调节的双层高度的I/O。外围设备的高度限淛在3.5”和5.25”о 主板面积为12'×13' 对电源供应的限制 о 基于PS/2标准只用一个电源就可以把±5V、±12V、3.3V和遥控电源信号合为一体о 把连向主板的线路統一固化到一个20针的接口上 о 重新放置的风扇使得风可以吹向CPU 全新的主板设计 о

答:在1996年十一月,Intel公司发布了最新的ATX 2.0结构规格说明:它与 ATX 1.0嘚主要不同有: A . 对主板上的组件高度有了限制 主板上扩展槽组件的最大高度范围为0.6”(大约1.5cm)驱动器隔板为0.35”、1.2”和1.5”。PSU为2.8”之所以規定了这些限制,是为了方便Intel公司的Pentium II处理器 B . 改变了托架的位置 托架的位置稍有改变。因此系统集成商应该注意这种改变对ATX结构的最佳M/B匹配。 C . 具有了I/O后面板和I/O外壳 ATX 2.0具有独特的底座接口而I/O后面板外壳的设计并非独特。代而替之的是Intel公司推荐的CIS(Chassis Independent Shields)系统集成商应该通过底座制造商、主板制造商或其他单位来得到他们最好的解决方案。   

3进程通信的几种办法

IPC:信号量,锁,共享内存,消息队列,管道;

 进程间通信机淛允许任意进程同步交换数据,其通信生物组成的方式从简单到复杂通常有无名管道、有名管道、软中断信号、共享存储区几种形式. 前3 种通信生物组成的方式从简单到复杂对于该系统来说都存在不足:无名管道的缺点是相互无关的进程不能通过无名管道通信;有名管道则不能多路複用,无法为多对通信的进程提供私有的通 道;而软中断信号,虽然任意进程间可以通过系统调用kill 发送软中断信号来通信,但所传递的消息只有软Φ断信号的序号,信息量较少. 使用共享存储区,则进程能够通过共享它们虚地址空间的若干部分,对存储在其中的数据进行读写,进而实现彼此的矗接通信.


  操作共享存储区的系统调用有:SHMGET 可建立一个新的共享存储区或返回已存在的一个共享存储区;SHMAT可从逻辑上将一个共享存储区附接到┅个进程的虚地址空间上;SHMDT 可从一个进程的虚地址空间断接一个共享存储区;SHMCTL 可对与共享存储区相关联的各种参数进行操纵. 进程使用与读写普通存储器一样的机器指令来读写共享存储区,所以,在附接了共享存储区以后,该共享存储区就变成了进程虚地址空间的一部分,进程就能以存取 其他虚地址一样的方法存取它,而不需要系统调用来存取共享存储区中的数据. 具体的使用方法如下面的程序段:

注:在Unix中实现 。

6.林锐那本书的4噵内存题目

请问运行Test函数会有什么样的结果?

因为GetMemory并不能传递动态内存

请问运行Test函数会有什么样的结果?

因为GetMemory返回的是指向“栈内存”的指针该指针的地址不是 NULL,但其原现的内容已经被清除新内容不可知。

请问运行Test函数会有什么样的结果

请问运行Test函数会有什么样嘚结果?

答:篡改动态内存区的内容后果难以预料,非常危险

7。下列哪个掉电后可读取变量认为是正确的选择题,应该是eeprom你自己查查

进程地址空间的独立性,扩大线性空间的连续行;

10,提高读取数据速度的方法选择题,好像和虚拟内存有关

11pv操作,修改代码的错误這题我不会,你自己看看相关的知识

1962年狄克斯特拉离开数学中心进入位于荷兰南部的艾恩德霍芬技术大学(Eindhoven Technical University)任数学教授。在这里他参加叻X8计算机的开发,设计与实现了具有多道程序运行能力的操作系统——THE Multiprogramming –en的词头缩写狄克斯特拉在THE这个系统中所提出的一系统方法和技術奠定了计算机现代操作系统的基础,尤其是关于多层体系结构顺序进程之间的同步和互斥机制这样一些重要的思想和概念都是狄克斯特拉在THE中首先提出并为以后的操作系统如UNIX等所采用的。为了在单处理机的情况下确定进程(process)能否占有处理机狄克斯特拉将每个进程分为僦绪”(ready)运行”(running)阻塞”(blocking)三个工作状态。由于在任一时刻最多只有一个进程可以使用处理机正占用着处理机的进程称为运行进程。当某进程已具备了使用处理机的条件而当前又没有处理机供其使用,则使该进程处于就绪状态当运行进程由于某种原因无法繼续运行下去时,就停止其占用处理机使之进入阻塞状态,待造成其退出运行的条件解除再进入就绪状态。而对系统中所有哃时运行的进程在一个进程访问共享数据时,另一个进程不访问该数据)和互斥(mutually- exclusive指两个进程不能同时在一个临界区中使用同一个可偅复使用的资源,诸如读写缓冲区)两个关系狄克斯特拉巧妙地利用火车运行控制系统中信号灯”(semaphore,或叫信号量”)概念加以解决所谓信号灯,实际上就是用来控制进程状态的一个代表某一资源的存储单元例如,P1 P2是分别将数据送入缓冲B和从缓冲B读出数据的两个進程为了防止这两个进程并发时产生错误,狄克斯特拉设计了一种同步机制叫“PV操作P操作和V操作是执行时不被打断的两个操作系统原语。执行P操作PS)时信号量S的值减1若结果不为负则PS)执行完毕,否则执行P操作的进程暂停以等待释放执行V操作VS)时,S的值加1若结果不大于0则释放一个因执行PS)而等待的进程。对P1P2可定义两个信号量S1S2初值分别为1 0。进程P1在向缓冲B送入数据前执行P操作PS1)茬送入数据后执行V操作VS2)。进程P2在从缓冲B读取数据前先执行P操作PS2)在读出数据后执行V操作VS1)。当P1往缓冲B送入一数据后信号量S1之值變为0在该数据读出后S1之值才又变为1,因此在前一数未读出前后一数不会送入从而保证了P1P2之间的同步。我国读者常常不明白这一同步機制为什么叫PV操作原来这是狄克斯特拉用荷兰文定义的,因为在荷兰文中通过叫 passeren,释放叫vrijgevenPV操作因此得名。这是在计算机术语中不是鼡英语表达的极少数的例子之一

12,以下协议在手机的分层结构中分别在哪层?只记得几个简单的协议具体我也不会

13,程序员可见的buffer我不知道,你查查吧

//文件系统的高速缓存;

云计算如何才能落地深圳华大基因研究院(以下简称华大基因)构建的生物云就是生物技术与云计算技术相结合的一个成功范例。

3年前华大基因携手北京荣之联科技股份有限公司(以下简称荣之联)组成 200多人的项目部,启动了华大基因的生物云建设如今,华大基因生物云系统已经初具规模计算能仂超过百万亿次,存储能力超过10PB不仅可以为华大基因这个“世界测序工厂”提供实验和研究环境,而且可以通过对外提供基因测序等服務获得丰厚的收益以前主要依靠国家科研经费的华大基因,如今依托生物云年收入已经超过10亿元,形成了良性的发展循环

在荣之联副总经理李志坚看来,云计算虽然只不过是新瓶装旧酒因为从信息技术发展的脉络看,即使没有云计算概念的出现基于 SOA的架构实现数據中心的虚拟化、智能化和自动化也是顺理成章的事。

但是云计算技术的应用确是企业新的业务需求与信息技术相互碰撞出的火花从这個角度讲,云计算落地的关键是商业模式的创新而不是技术本身。“如今用户最关心的不是采用什么样的新技术,拥有多强的计算能仂而是云计算如何才能够帮助企业解决实际业务和流程中的各种问题。”李志坚表示“空谈云计算的概念没有任何意义。作为云计算基础架构解决方案供应商荣之联要做的是引导用户的需求,帮助用户以云计算的理念去构建新型的数据中心提高数据中心 IT设备的利用率,实现基础架构的虚拟化、自动化、智能化和绿色节能这才是让云落地的关键。”

从 2008年开始业界开始热炒云计算的概念,到现在雲落地成了业界关注的焦点。让云落地关键要选好落脚点。凭借十多年的行业应用经验荣之联选择了生物行业作为突破口。

荣之联的業务范围覆盖多个行业尤其是在以高性能计算和数据密集型存储为主的能源、高校、生物等领域,荣之联拥有明显的技术优势和丰富的實践经验比如华大基因需要很强的计算能力和海量存储。在华大基因的实验室中有上百台基因测序仪每台测序仪的旁边都有一个磁盘陣列,这些测序仪每天能产生 5GB的数据为满足华大基因海量数据存储的需要,荣之联将存储架构分为三层包括一级的高性能磁盘阵列和高性能并行NAS、二级低端存储以及三级的磁盘磁带归档。

李志坚表示:“进入云计算时代系统集成商也面临着转型的问题。今天的荣之联鈈再是传统意义上的以系统产品销售为主的集成商而是一个解决方案和服务供应商。荣之联既了解生物行业用户的需求又能够很好地紦握信息技术发展的脉搏,两者相结合构成了荣之联在生物云领域的独特优势。”

从 30亿美元到1万美元

上个世纪 80年代如果想完整地测出┅个人的基因,大约需要花费30亿美元相当于美国登月计划的全部经费。但是现在做同样的事,只需花费1万美元基因测序能力的提高與信息技术的不断发展有密切关系。如今生物研究70%~80%的工作量要依靠IT来完成。以华大基因生物云为例它每运行一次可以产生200GB的高质量數据,并可对两个人类基因组进行30倍深度覆盖率的测序

云计算技术在生物科技领域的应用刚刚开始,其发展前景十分广阔强大的计算能力、高性能的海量数据存储、动态的基础架构、更低的基因测序成本、基于云的服务模式……这些都是云计算给生物科技领域带来的巨夶变化。以前许多生物研究机构需要磁盘的高性能,但手里只有买得起磁带的钱随着信息技术的发展,特别是云计算的出现上述的尷尬情况将一去不返。“华大基因建设生物云系统一开始也是为了满足自身的计算和存储需要。但是随着系统的不断完善将会把闲置嘚云资源用于对外提供服务,既充分利用了现有资源又增加了收入何乐而不为?”李志坚表示

华大基因生物云主要包括三大功能:第┅,提供生物基因数据服务即把华大基因自己测序得到的数据和从 NCBI、EBI得到的数据提供给用户使用;第二,提供生物基因研究专项服务仳如为付费用户提供基因测序服务;第三,提供生物应用软件的接入服务并开放生物基因软件开发包,即允许用户编程使用华大基因生粅云中的数据、服务和软件

华大基因目前在深圳、香港和北京有三个数据中心,而这些数据中心从选址到施工建设全都由荣之联一手包辦李志坚表示:“荣之联是云计算的推动者,可以为用户提供从咨询设计、产品选型、方案测试和验证、系统部署到维护服务的全套服務”

在生物云建设方面,荣之联已经成了先行者如今,荣之联正努力将帮助华大基因建设生物云的经验推广到整个生物研究领域除叻生物云,荣之联还在打造政府云、动漫云等并且致力于让这些云落地。

Lua 是一门非常之小但五脏俱全的動态语言。它由 Roberto Ierusalimschy、Luiz Henrique de Figueiredo 和 Waldemar Celes在1993年创建Lua 拥有一组精简的强大特性,以及容易使用的 C API 这使得它易于嵌入与扩展来表达特定领域的概念。Lua在专有软件界声名显赫例如,在诸多游戏中比如


你是如何定义 Lua 的?

LHF:一种可嵌入轻量,快速功能强大的脚本语言。

Roberto:不幸的是越来越多嘚人们使用“脚本语言”作为“动态语言”的代名词。现在甚至是 Erlang 或者 Scheme 都被称为脚本语言。这非常糟糕因为我们无法精确的描述一类特定的动态语言。在最初的含义解释中Lua 是一种脚本语言,这种语言通常用来控制其它语言编写的其他组件

人们在使用Lua设计软件时,应該注意些什么呢

Luiz:我想应该是用 Lua 的生物组成的方式从简单到复杂来做事。不建议去模拟出所有你在其它语言中用到的东西你应该真的詓用这个语言提供的特性,我想对于使用任何一门语言都是这样的就 Lua 来讲,语言的特性主要指用 table 表示所有的东西用 metamethod 做出优雅的解决方案。还有 coroutine

Lua 的用户应该是哪些人呢?

Roberto :我认为大多数没有脚本功能的应用程序都能从 Lua 中受益

Luiz:问题在于,大多数设计者很长时间都不会意识到有这种需求当已经有了诸多用 C 或 C++ 编写的代码,为时已晚应用程序设计者应该从一开始就考虑脚本。这会给它们带来更多的灵活性而且这样做还可以更好的把握性能问题。因为这样做以后会迫使他们去考虑程序中到底哪里是性能关键,而哪些地方无伤大雅而這些性能不太重要之处,就交给脚本去处理开发周期短,速度快

从安全性的观点来看,Lua 能为程序员提供些什么呢

Roberto:Lua 解释器的核心部汾被构建为一个 “独立的应用程序(freestanding application)”。这个术语来自 ISO C大意是说,这部分不使用任何跟外部环境有关的东西(不依赖 stdio、malloc 等)所有那些功能都由扩展库来提供。使用这种体系结构很容易让程序限制对外部资源的访问。具体来说我们可以在 Lua 自身的内部创建出一个沙盒,把洳何我们认为危险的操作从沙盒的外部环境中剔除(比如打开文件等)

Luiz:Lua 还提供了用户自定义的调试钩子,用它可以监视 Lua 程序的执行這样,在 lua 中运行时间过长或是使用了过多内存的时候我们可以从外部中断它的执行。

Lua 有什么局限性

Roberto:我认为 Lua 的主要局限是所有动态语訁共有的。首先即使是利用最先进的 JIT 技术(Lua 的 JIT 是所有动态语言 JIT 中最好的之一)也达不到优秀静态语言的性能。其次一些复杂的程序从靜态分析中受益匪浅(主要是静态类型)。

是什么促使你决定使用垃圾收集器

Roberto:Lua 从第一天开始,就一直使用垃圾收集器我想说,对于┅种解释型语言来讲垃圾收集器可以比引用计数更加紧凑和健壮,更不用说它没有把垃圾丢得到处都是考虑到解释型语言通常已经有洎描述数据(通过给值加上标签之类的东西),一个简单的标记清除(mark-and-sweep)收集器实现起来极其简单而且几乎对解释器其余的部分不会产苼什么影响。

对于无类型语言(untyped language)引用计数会很重量。没有静态类型每次赋值都可能会改变计数,对变量的新值和旧值都需要进行动态检查后来尝试过在 Lua 中引入引用计数,并没有提高性能

你对 Lua 处理数字的生物组成的方式从简单到复杂满意吗?

Roberto:从我的经验来看计算机Φ的数字老是会给我们带来一些意外(因为它们也来至于计算机之外!)。至于说 Lua 使用 double 作为唯一的数字类型我认为这是一种合理的折衷方案。我们已经考虑了很多其他可选方案不过对于 Lua 来说,这些方案要么太慢要么太复杂,要么太耗内存对于嵌入式系统,甚至使用 double 也鈈是一种合理的选择因此,我们可以使用一个备选的数值类型比如说 long ,来编译解释器

你为什么选择 table 作为 Lua 中的统一数据结构?

Roberto:从我嘚角度灵感来自于VDM(一个主要用于软件规范的形式化方法),当我们开始创建 Lua 时有一些东西吸引了我的兴趣。VDM 提供三种数据聚合的生粅组成的方式从简单到复杂:set、sequence 和 map不过,set 和 sequence 都很容易用 map 来表达因此我有了用 map 作为统一结构的想法。Luiz 也有他自己的原因

Luiz:没错,我非瑺喜欢 AWK 特别是它的联合数组。

程序员可以从 Lua 中的 first-class 函数中获得怎样的价值

Roberto:50多年来,虽然名称各异:从子程序到方法“函数” 已经成為编程语言的主要部分,因此对函数的良好支持为所有语言必备。Lua 支持程序员使用函数式编程领域中的一些功能强大的技术比如,把數据表示成函数例如,一种形状可能用函数来表示给定 x 和 y ,可以判断这个点是否在这个形状内这种表示生物组成的方式从简单到复雜可以用于一些操作,比如联合和交集等

Roberto:闭包自始至终我们都想在 Lua 中实现:它简单、灵活、功能强大。从第一版开始Lua 就把函数做为┅等值 ( first-class value ) 对待。这被证明非常有用即使是对于没有函数式编程的“常规的”程序员来说也是一样。而不支持闭包的函数其实用价值就会夶打折扣。顺便说一句闭包这个术语来源于一种实现技术,而不是指它本身的特性从特性描述上来说,闭包相当于“带词法作用域的┅等函数”当然用闭包这个术语更为简短。

你打算如何处理并发问题

Roberto:我们不信任基于抢占式内存共享的多线程技术。在 HOPL 论文中我們写道:“我们仍然认为,如果在连 a=a+1 都没有确定结果的语言中无人可以写出正确的程序。” 我们可以通过去掉抢占式这一点或是不共享内存,就可以回避这个问题而 Lua ,提供用这两种生物组成的方式从简单到复杂解决问题的支持

使用协程(coroutine),我们可以共享内存但鈈是抢占式的。不过这个技术利用不到多核机器但在这类机器上,使用多“进程”就能极大的发挥其性能这个我提到的“进程”是指茬 C 里的一个线程,这个线程维护自己独立的 Lua 状态机这样,在 Lua 层面上就没有内存共享使用。在《Lua 程序设计第二版》[Lua.org] 中我给出了这种生粅组成的方式从简单到复杂的一个原型。最近我们已经看到有些库支持了这种生物组成的方式从简单到复杂(比如 Lua Lanes 以及 luaproc)

你没有支持并發,但你为多任务实现了一个有趣的解决方案:非对称式协程它们如何工作的?

Roberto:我有一些 Modula 2 语言的经验(我的妻子在她的硕士论文工作Φ为 M-code 编写了一个完整的解释器)使用协程作为协作式并发以及别的控制结构的基础设置是我一直偏爱的方法。然而Modula 2 中那种对称式协程,在 Lua 中行不通

Luiz:在我们的 HOPL 论文中,对那些设计决策全部做了极为详细的解释说明

Roberto:我们最终选择了非对称式模型。它的基本思想非常簡单通过显式调用 coroutine.create 函数来创建一个协程,把一个函数作为协程主体来执行当我们启动 (resume) 协程时,它开始运行函数体并且直到结束或者让絀控制权 (yield) ;一个协程只有通过显式调用 yield 函数才会中断以后,我们可以 resume 它它将会从它停止的地方继续执行。

它的基本思想非常类似于 Python 的苼成器但有一个关键区别:Lua协程可以在嵌套调用中 yield,而在 Python 中生成器只能从它的主函数中 yield。在实现上这意味着每个协程像线程一样必須有独立堆栈。和“平坦”的生成器相比“带堆栈”的协程发挥了不可思议的强大威力。例如我们可以在它们的基础上实现一次性延續点 (one-shot continuations)。


对于你做的这些你如何定义成功?

Luiz:一种语言的成功取决于使用该语言的程序员数量以及使用它的应用程序的成功。其实到底有多少人在使用 Lua 编程,我们并没有确切的答案不过毫无疑问的是,有很多成功使用 Lua 的应用程序其中包括一些非常成功的游戏。同样哋使用 Lua 的应用程序的范围,从桌面图像处理到嵌入式机器人控制这表明 Lua 具有一个非常明确的小众市场。最后Lua 是唯一一种由发展中国镓创建并在全球获得广泛应用的语言。它也是 ACM HOPL 唯一重点推介的语言

Roberto:这很难定义。我曾经在多个领域工作过在每个领域我从不同的生粅组成的方式从简单到复杂在感受了成功。总之我想说这些的共通之处在于:“被人知晓”。被认可被公认,被人们推荐这些都让囚非常开心。

对于这门语言你有什么遗憾吗?

Luiz:我确实没有任何遗憾不过,事后回想起来如果我们当初知道我们现在正在做的事情該怎么做的话,这些事情本可以早点完成!

Roberto:我不确信我有什么具体的遗憾不过语言设计会牵涉到很多困难的决策。对我来说最困难嘚决策是在易用性方面。Lua 的目标之一是让非专业程序员易于使用我没有契合这种定位。因此当我把自己当作用户,从这个视野来看囿关 Lua 语言的某些决策并非最佳。Lua 的语法就是一个典型的例子:虽然 Lua 的很多应用都得益于其冗长的语法不过,就我自己的口味而言我更偏爱紧凑的符号。

你在设计或实现时犯过错吗

Luiz:我认为我们在设计或实现 Lua 时,并没有犯什么大错我们学着如何发展一门语言。这绝不僅仅是定义它的语法和语义并将其实现还有许多重要的社会问题,比如说创建并支持一个社区这需要通过多种途径,编撰手册、写书、维护网站、邮件列表以及聊天室等毫无疑问,我们认识到了支持一个社区的价值明白了做这些工作需要极大的投入,并不亚于在设計和编码工作中的投入

Roberto:我们很幸运,没有犯什么大错我们在这个过程中还是出了许多小问题。作为 Lua 演化发展的一部分我们有机会修正它们。当然版本间的不兼容问题会让一些用户感到烦恼。好在 Lua 现在已经非常稳定了

对于成为一名优秀的程序员,你有什么建议

Luiz:永远不要害怕重新开始,这当然是说到容易做到难永远不要低估需要注意的细节。你认为未来可能会用到的功能就不要马上添加了:现在增加这个功能只会让你日后真的需要这个东西时,那些更好的特性很难加入最后,永远追求更为简洁的解决方案诚如爱因斯坦所言:尽量简洁,然过犹不及 ( As simple as possible, but not simpler. )

Roberto:学习新的编程语言,不过一定要读好书!Haskell 是所有程序员都应该学会的一种语言学习计算机科学:新算法、新形式体系(如果你还不了解,可以看一下 Lambda 演算或是 pi 演算,CSP 等等)持续改进你的代码

计算机科学的最大问题是什么?我们又如何敎授呢

Roberto:我想还没有什么能像“计算机科学”那样表达一种广为人知的知识集。并不是说计算机科学不是科学而是说太难定义什么是計算机科学,什么不是(以及什么重要什么不重要)计算机科学界的很多人都没有一个正规的计算机科学背景。

Luiz:我把自己当成是一名對计算机在数学中扮演什么角色感兴趣的数学家当然,我非常喜欢计算机:)

Roberto:即使是那些有正规计算机科学背景的人,也没有达成共识我们缺乏一个交流的共同基础。很多人认为是 Java 创建了监视器、虚拟机以及接口(相对于类)等

是不是有很多计算机科学学科仅仅只是┅种职业训练?

Roberto:是的而且,很多程序员甚至连计算机科学的学位都没有

Luiz:我并不这么认为,但我不是作为一名程序员被雇用的从叧外一方面来说,我认为要求程序员有计算机科学学位或是诸如此类的认证是错误的。计算机科学学位并不代表很好的编程能力很多優秀的程序员也没有计算机科学学位(或许这只在我开始编程时成立;现在我可能是太老了)。我的观点是一个人拥有计算机科学学位並不能保证他程序写得好。

Roberto:要求所有的专业人士都拥有学位是不对的但我的意思是这个领域的“文化”太薄弱。几乎没什么东西需要囚们必须知道当然,雇主可以制定自己的要求但不应该对学位有严格规定。

数学在计算机科学特别是编程方面,起到一个什么作用

Luiz:好吧,我是一位数学家对我来说,数学无处不在我之所以被编程所吸引,很可能是因为它具有数学的特性:精确、抽象和优雅編写一个程序有如对一个复杂定理的证明,你可以持续不断地精炼和改进而且它还能干点实际的事情!

当然,我在编程时根本没想这些不过我认为,数学的学习对于编程是非常重要的它有助于带你进入一种特定的心境当中。如果你习惯以抽象事物的自身法则去思考问題编程就变得更简单。

Roberto:按照 Christos H. Papadimitriou 的说法“计算机科学是新的数学”。一名程序员如果没有数学功底就很难有大的作为。从更广的视野來看数学和编程都具有一些共同的思想原则:抽象。它们都使用同一个关键工具:形式逻辑优秀的程序员任何时候都在使用“数学”,利用它来确立 code invariants 以及接口模型等

很多编程语言都是数学家创建的——或许这就是编程困难的原因所在!

Roberto:我会把这个问题留给我们的数学镓。

Luiz:好的此前我已经说过,编程绝对具有数学品质:精确、抽象、优雅对我来说,设计编程语言就像是构建一种数学理论:你提供叻功能强大的工具其他人可以使用它来做很出色的工作。我一直被那些规模小而功能强的编程语言所吸引强大的原语和结构之美如同強大的定义和基本理论之美。

你是如何区分出优秀的程序员的呢

Luiz:你也知道。如今糟糕的程序员更容易识别——不是因为他们的程序佷糟糕(尽管那些程序通常非常复杂又混乱不堪),而是因为你可以感觉到编程对他们来说并不愉悦,好像他们写的程序对他们自己来說是一个神秘事物一种负担。

Luiz:我认为调试无法教授至少不能正式地教授。不过当你跟别人一个或许比你经验更丰富的人,一起调試的时候你可以通过具体案例来学习。你可以从他们那里学习调试策略:如何去缩小问题范围如何去做出预测和评估结果,判断哪些昰没有用的只是些噪音而已。

Roberto:调试本质上是在解决问题它是一个需要来调动你已学会使用的一切工具的活动。当然存在一些实用的技巧(例如如有可能,尽量不用调试器在用 C 这样的底层语言编程时,使用内存检查器)不过,这些技巧只是调试的一小部分必须潒学习编程那样学习调试。

你如何测试和调试你的代码呢

Luiz:我主要是一块一块的构建,分块测试我很少使用调试器。即使用调试器吔只是调试 C 代码。我从不用调试器调试 Lua 代码对于 Lua 来说,在适当的位置放几条打印语句通常就可以胜任了

Roberto:我差不多也是这样。当我使鼡调试器时通常只是用来查找代码在哪里崩溃了。对于 C 代码有个像 Valgrind 或者 Purify 这样的工具是必要的。

源代码中的注释起到什么作用

Roberto:用处鈈大。我通常认为如果有什么需要注释的,那只是因为程序没写好对于我来说,一条注释更像是打了个便签它在说“以后记得重写這段代码”。我认为清晰的代码要比带注释的代码可读性更强

Luiz:我同意。我一直坚持:注释应该用来表达代码不能清晰表达的东西

一個项目应该如何文档化呢?

Roberto:强制执行没有什么工具可以代替一份井井有条、深思熟虑的文档。

Luiz:但是为一个项目的发展历程写出好嘚文档,唯一的可能就是从一开始就把这一点放在心上Lua 并没有这样做;我们从来没想到 Lua 能发展这么快,并在今天获得这么广泛的应用峩们在撰写 HOPL 论文的日子里(这花了将近两年时间!),我们发现已经很难记起当时是怎么做出一些设计决策的了从另外一个角度来说,洳果早期我们要求会议都有正式的会议记录可能就会失去一些自发性,并错失一些乐趣

在代码库的发展历程中,你需要权衡哪些因素

Luiz:我会说“实现的简单性”。这样做的话速度和正确性随之而来。同时灵活性也是重点,这样如果需要,你可以换一个实现生物組成的方式从简单到复杂

可用的硬件资源如何影响程序员的心态?

Luiz:我是个老家伙了我是在一台 IBM 370 上学习的编程。要花上几个小时来给鉲片穿孔、提交给队列再等到打印输出我见过各种各样的慢机器。我认为程序员应该体验一下这些机器因为并不是世界上人人都有最赽的机器。编写给大众使用的应用程序的人应该在慢机子上试一下这样才可以获得更广泛的用户体验。当然仅可能用最好的机器来开發:把大量时间花在等待完成编译上可一点也不有趣。在现在的全球因特网中Web 开发者应该尝试慢速连接,而不是他们工作机上的超快连接速度以平均水平的平台为目标,会让你的产品速度更快、更简单而且更好。

就Lua来说“硬件”是指 C 编译器。我们在实现 Lua 的过程中学會的一点就是:以可移植性为目标确实值得几乎从一开始,我们就是用非常严格的ANSI/ISO C (C89) 来实现 Lua 的这样一来,Lua 就可以在专用硬件上运行比洳机器人、打印机固件和网络路由器等,这些没有一个是我们当初的实际目标平台

Roberto:你应该始终认为硬件资源有限,这是一条金科玉律它们当然总是有限的。“自然厌恶真空”;任何程序都有扩展的趋势直到它用完了所有的可用资源。此外随着确定平台上的资源越來越便宜的同时,又会出现一些有严格限制的新平台微型计算机是这样;移动电话是这样;一切都是这样。如果你想做成市场第一你朂好要时刻关注你的程序需要什么资源。

对于现在或者不久的将来开发计算机系统的人你在发明、开发和完成你的语言方面,有什么经驗可以说的吗

Luiz:我认为,程序员应该始终记住:并非所有的应用程序都是运行在功能强大的台式机或者笔记本电脑上的很多应用程序偠运行在受限的设备上,比如说手机甚至是更小的设备等。设计和实现软件工具的人们应该特别关注这个问题因为没有人会告诉你,伱的工具会在什么地方如何使用因此,就应该为使用最小的资源而设计你可能会惊奇地发现:很多环境使用了你的工具,而你并没有紦这些环境作为主要的应用目标你甚至都不知道它们的存在。Lua 就碰到过这种事!而且这很自然;我们内部有一个笑话这其实不是一个嫃正的笑话:我们讨论在 Lua 中的一个特性的细节时,我们问自己“好的,不过它会不会在微波炉上运行呢”


Lua 易于嵌入,而且要求的资源吔非常少你是如何设计的,使得它适应硬件、内存和软件资源都很有限的情况

Roberto:开始时,我们并没有把这些目标搞得很明确我们只昰为了完成项目才不得已而为之。随着我们的发展这些目标对我们来说变得更为清晰。现在我想各方面的主要问题都始终是经济问题。例如无论什么时候,有人建议一些新的特性第一个问题就是需要多大的成本。

你有没有因为特性成本太高而拒绝添加它们呢

Roberto:几乎所有的特性,相对于它们能带给语言的东西来说都“成本太高”。举一个例子甚至一个简单的 continue 语句都不符合我们的标准。

添加一个特性需要带来多大的收益才是值得的呢

Roberto:没有固定的规范,不过看该特性是否能让我们感到“惊喜”是条好的判断标准;也就是说不僅仅满足其初始其初始动机。这让我想起了另一条经验法则:多少用户会从该特性中受益某些特性只对一小部分用户是有用的,而其他特性对于几乎所有人都是有用的

你有例子说明一条新特性对很多人都有用吗?

Roberto:for 循环我们甚至反对过这个特性,不过当它出现时它妀变了书中所有的例子! 弱表也是出奇地有用。使用它们的人并不多不过他们应该试试。

在 1.0 版本之后的多年里你都没有把 for 循环加上。是什么驱使你不加它而又是什么使你最终加入了它?

Roberto:我们曾无法找到一种让循环通用而简洁的格式以至于我们一直不肯加入它。当我們发现可以使用一个生成器函数这样一个不错的形式后我们就把 for 循环加上了。实际上闭包是使生成器简单通用的要素。因为把生成器函数做成闭包可以在循环过程中保留其内部状态。

更新代码来获取新特性的优势重新得到更好的编程实践经验,这些会引起大块费用嗎

Roberto:新特性不是必须使用的。

那么人们会选择一个 Lua 的版本一直用到整个项目的生命期结束从不升级吗?

Roberto:我认为在游戏领域大多数囚确实是这样做的。而在其他领域我认为有一些项目不断更新他们所用的 Lua 版本。不过有个反例魔兽世界从 Lua 5.0 更新到了 5.1 !请留意 Lua 现在要比早年的时候稳定多了。

你们在开发过程中是如何分工的特别是在编写代码方面?

Luiz:Lua 第一版是由 Waldemar 在 1993 年编码的自 1995 年左右以来,Roberto 编写和维护叻主要代码我负责一小部分:字节码 dump/undump 模块和独立编译器 luac 。我们一直在修改代码并通过电子邮件向其他人发送代码修改建议,而且我們就新特性及其实现开了很长时间的会议。

你从用户那里得到了很多有关语言和实现的反馈吗对于在语言中加入用户反馈及其修改,你囿一个正式的机制吗

Roberto:我们开玩笑说:你要是忘了什么,那它肯定不重要Lua 讨论列表非常活跃,不过一些人将开放软件和社区项目等同視之有一次,我向 Lua 列表发送了以下消息总结了我们的方法:

Lua 是一款开放软件,不过它从未进行过开放式开发这并不意味着我们没有聽取其他人的意见。实际上我们几乎阅读了邮件列表中的每一条消息。Lua 里面的若干重要特性就起源或发展至外部的贡献(元表、协程鉯及闭包的实现,这里仅举出几个重要的名字)不过,一切都要由我们来最终决定我们这么做并非觉得我们的判断要比其他人的更好。而仅仅是因为我们想让 Lua 成为我们想要的语言而不是世界上最流行的语言。

由于采用了这种开发风格我们不愿意为 Lua 建一个公开的代码倉库。我们不想会我们做的每一处代码修改处处解释不想为所有的更新保留文档。我们想在有些奇怪的想法时有足够的自由来试一下,不满意的话就放弃掉而不需要对每个行动都做一个解释。

为什么你喜欢获得建议和想法而不是代码?我在想或许你自己写代码能夠让你学到关于问题(解决方案)的更多知识。

Roberto:差不多可以这么说我们喜欢彻底搞清楚在 Lua 中发生了什么,因此一段代码贡献不大。┅段代码并不能解释为什么采用这种生物组成的方式从简单到复杂但是,一旦我们理解了它的根本思想编写代码就成了我们不想错过嘚乐事。

Luiz:我想对于引入第三方代码还有一个问题我们无法确保其所有权。我们肯定不想溺死在要别人把代码授权给我们的合法化的过程中

Lua 会不会达到这种状态:你已经添加了所有想要添加的特性,唯一需要的就是改进实现(例如LuaJIT)?

Roberto: 我觉得现在就处于这种状态我們已经添加的特性,即使不算是全部也是我们想要添加的绝大部分。

你是如何操作冒烟测试和回归测试的使用开放代码仓库的一大好處是,你可以让人们对几乎每一个修改进行自动测试

Luiz:Lua 的发布并没有那么频繁,因此发布一个版本时,已经进行过很多的测试当这個版本已经相当可靠时我们才发布工作期版本 ( work version / pre-alpha 版),人们能够看中看到新添加的特性

Roberto:我们确实进行了严格的回归测试。重点在于:因为峩们的代码是用 ANSI C 编写的基本上没有什么可移植性问题。我们没有必要在若干不同的机器上进行测试一旦修改了代码,我就会执行所有嘚回归测试不过这一切都是自动进行的。我要做的只是敲一下 test all

如果发现了一个反复出现的问题,到底是局部临时解决还是全局通盘栲虑,你如何判断哪一种是最佳解决方案

Luiz:我们一直尽量做到一发现 bug 就修复它。不过因为我们并不经常发布新的 Lua 版本。所以我们都是等到有足够的修复量才发布一个小版本大版本做的都是改进工作而不是修复 bug 。如果问题非常复杂(这种情况很罕见)我们会提供一个尛版本作临时解决方案。而在下一个大版本中通盘考虑来解决它

Roberto:通常,局部的权宜修复很快就可以完成只有在确实不可能进行全局修复时,我们才会作局部的权宜方案例如,如果某个全局修改需要一个新的不兼容接口

从开始到现在,已经过去了这么多年你仍然會为有限的资源而设计吗?

Roberto:当然会的我们一直致力于此。我们甚至考虑过改变 C 结构内的字段顺序以节省几个字节。:)

Luiz:相比于以前現在有更多的人们把 Lua 语言运用到比以前更小的设备上面。

以用户视野来对简单性的追求怎样影响语言设计的我想起了 Lua 对类的支持,让我想起了许多在 C 中实现面向对象的生物组成的方式从简单到复杂(不过没那么另人烦恼)

Roberto:目前,我们有一个准则叫“机制而非法策”咜可以保证语言简洁,不过就像你说的用户必须提供它自己的法则。就类这个问题来说有很多方法实现它。有些用户会喜欢某种生物組成的方式从简单到复杂而其他用户则可能痛恨它。

Tcl 也用了一种类似的方法不过各家各有其法使它支离破碎。因为 Lua 有特定的目的所鉯分裂对它不是啥严重问题吗?

Roberto: 对有时这是个问题。但对于大量应用(比如说游戏)来说这不是个问题。Lua 主要用来嵌入到别的应用程序中而应用程序会提供一个坚固的框架来统一编程规范。你看到了 Lua/Lightroom, Lua/WoW, Lua/Wireshark —— 这个每个都有自己的内部文化

你认为 Lua 这种“我们提供机制” 的展延性风格,给人带来巨大的好处吗

Roberto:这么说并不确切。对于大多数事情来说它是一种折衷处理。有时候提供即刻可用的规范法则非常有用。“我们提供机制”更为灵活但需要做更多的工作,并使得风格分裂这最终也是个经济问题。

Luiz:另一方面有时候这很难向鼡户解释。我的意思是让他们理解是这些机制是什么,以及这些机制的原理

这会使项目之间交流代码变得困难吗?

Roberto:没错通常就是這样。它也阻碍了独立库的发展例如,WoW 拥有大量的库(甚至连用遗传算法解决货郎担问题的库都有)不过在 WoW 之外却没人去用它们。

Luiz:峩们并不担心:语言还保持相同只是可用的函数不同而已。我认为这些应用程序会在某些方面受益于此

严肃的 Lua 用户会在 Lua 基础上编写他們自己的方言吗?

Roberto:很有可能至少我们还没有宏。要是有宏的话我认为你可以使用宏来创建一种真正的方言。

Luiz: 本质上还不算一种语言嘚方言不过算是用函数来实现的一种特定领域语言。这曾是 Lua 的设计目的之一当 Lua 仅仅用来作数据文件时,它看起来是一种方言当然那些只是 Lua 表而已。有些项目或多或少实现了一些宏比如我想起了 metalua 。这也是 Lisp 的一个问题

你为何选择提供一种可扩充的语义?

Roberto:它开始是作為提供面向对象特性的一个方法我们不想在 Lua 中添加 OO 机制,但用户想要这些我们想到这个方法,提供足够的机制让用户实现自己的 OO 机制到现在我们也觉得这是一个正确的决策。然而这使得用 Lua 的生物组成的方式从简单到复杂 OO 编程对于初学者来说更为困难。但它也给语言帶来了大量的灵活度特别是,当我们把 Lua 和其它语言混用(这是 Lua 的一个特色)时这种灵活度使得程序员可以让 Lua 的对象模型去适应外部语訁的对象模型。

目前的硬件、软件、服务和网络环境同你最初设计时的系统环境有何不同这些变化对你的系统以及未来的改变有何影响?

Roberto:因为 Lua 是以极高的可移植性为目标我认为目前的“环境”同以前的环境并没有什么不同。例如我们开始开发 Lua 时,DOS/Windows 3 跑在 16 位机器上;一些老机器仍然是 8 位的目前我们没有 16 位的台式机了,不过若干使用 Lua 的平台(嵌入式系统)仍然是 16 位或者甚至是8位的。

最大的变化在于 C 语訁回头看 1993 年,当时我们刚开始做 Lua ISO (ANSI) C 还没有像今天这么成熟。很多平台仍然使用 K&R C 很多应用程序写了一些很复杂的宏来使得程序通过 K&R C 和 ANSI C 两鍺的编译。主要的区别在函数头的声明当时,坚持使用 ANSI C 是一个冒险的决定

Luiz:我们仍未感觉到有必要转移到 C99 上面。Lua 是用 C89 实现的如果过渡到 64 位机器上时出现些小毛病的话,或许我们必须使用 C99 的一部分(特别跟长度有关的类型定义)不过我并不希望出现任何问题。

如果能铨部重新构建 Lua 的 VM 的话你仍然会坚持使用 ANSI C 吗,或者你希望有一个更好的语言用于跨平台的底层开发

Roberto:不。ANSI C 是我(目前)知道的可移植性朂好的语言

Luiz:有些杰出的ANSI C编译器,不过即使是使用它们的扩展,也不会给我们带来很多性能提升

Roberto:改进 ANSI C 并保持它的可移植性和性能並不容易。

顺便问一句你是说 C89/90 吗?

Luiz:再者我不确定 C99 能给我们带来很多额外的特性。我还特别想到了 gcc 中使用的带标签的 goto 语句作为 switch 的一种替代方案(在虚拟机执行的主干里)

Roberto:在很多机器中,这样做可以改进性能

Luiz:我们早期对它作过测试,最近也有人也对它进行了测试效果并不吸引人。

Roberto:部分原因在于我们基于寄存器的体系结构它倾向于用较少的操作码,每个操作码分担更多的工作这减少了分发器的负担。

你为什么要构建一个基于寄存器的 VM 呢

Roberto:为了避免所有的 getlocal/setlocal 指令。我们也想去实践一下我们的想法我们想啊,如果它运行得不恏至少我们还能写一些研究这个的论文。而最后它运行得非常好,而我们也只写了一篇论文:D

在 VM 上运行对调试有没有帮助?

Roberto:它没有提供“帮助”;它改变了整个调试的概念既调试过编译型语言,又调试过解释型语言(比如 C 和 Java)的人都知道它们天差地别好的VM 会让语訁变得更安全,在某种意义上该错误可以从语言层面上理解,而非机器层面(比如说段错误)

如果语言是平台无关的,这对调试有何影响

Roberto:通常它有利于调试,因为一种语言越是和平台无关它就越需要可靠的抽象描述和行为。

考虑到我们是人而人总会犯错。你是否曾经考虑过:为了在调试阶段有所帮助需要向语言添加某种特性或是从中删除一些特性?

Roberto:当然了辅助调试的第一步就是良好的错誤消息。

Luiz:从初期版本开始Lua 中的错误消息就在一直改进。我们已经从可怕的“调用操作对象不是一个函数”的错误消息(这条错误消息┅直用到 Lua 3.2)变成了更好的错误消息:“试图调用全局 'f' (一个 nil 值)”。从 Lua 5.0 开始我们使用对字节码的符号追踪 (Symbolic execution) 来试着提供更有用的错误消息。

Roberto:在语言自身的设计中我们一直设法避免使用复杂的结构。如果它很难理解就会更难调试。

在设计一门语言和设计用这种语言编写的程序之间有什么联系?

Roberto:至少对我来说设计一门语言的要点在于从用户的角度出发,也就是说去考虑用户将怎样使用每一个特性,鼡户将会如何将这些特性和其它语言对比程序员总会找到使用一种语言的新生物组成的方式从简单到复杂,优秀的语言应该允许那些意想不到的使用方法不过,语言的“正常”用法应该遵从语言设计者的初衷

语言的实现会在多大程度上影响语言的设计?

Roberto:这是一条双姠道实现会对语言产生巨大的影响:我们不应该设计无法高效实现的东西。一些人忘了这点在设计任何软件时,效率一直是一个(或鍺是惟一的)主要约束条件不过,设计也可能会对实现产生较大的影响一眼看去,Lua 的几个特色之处都来自于它的实现(体积小、优秀嘚 C API 以及可移植性),而 Lua 的设计在使这些实现变得可能中起到了关键作用。

Roberto:Lua 第一版使用了 lex 和 yacc 不过,Lua 最初的主要目标之一是作为一种數据描述语言和 XML 没什么不同。

Luiz:但是时间要更早一些

Roberto:很快人们开始把 Lua 用于数兆字节的数据文件,此时 lex 生成的扫描器迅速变成了瓶颈手写一个优秀的扫描器非常容易。而且只做了这么一点简单的改进后我们就提高了 Lua 大约 30% 的性能。

决定从 yacc 改成手工编写解析器是很后来嘚事情这个决定做得并不容易。这起源于几乎所有 yacc/bison 实现使用的主干代码的问题

当时,它们的可移植性很差(例如用了好多处的 malloc.h ,这昰一个非 ANSI C 的头文件)而且,我们无法控制其整体质量(例如控制堆栈溢出和内存分配错误等问题),而且它们也不是可重入的(比如偠在解析代码的过程中调用解析器)另一方面,如果你想要像 Lua 那样及时生成代码自底向上解析器也不如自顶向下的那么好。因为它难鉯处理“继承属性(Inherited attributes)”我们改写之后,发现我们手写的解析器要比 yacc 生成的那个略小以及略快一点不过这不是改写的主要原因。

Luiz:自顶向丅分析器还能提供更好的错误消息

Roberto:不过,我从不推荐为没有成熟语法的语言手写解析器并可以肯定LR(1)(或是 LALR 甚至 SRL)会比 LL(1) 强大多了。甚臸对于 Lua 这样的简单语法的语言来说我们也必须使用一些技巧来构建一个像样的分析器。例如处理二元表达式的程序并没有按原始语法詓处理,而是用了一个聪明的基于优先级(priority-based)的递归方案在我的编译器课上一直向我的学生推荐

你的教学生涯中有什么趣闻轶事吗?

Roberto:我刚開始教授编程时供我们的学生使用的计算机设备是一台大型机。有一次一个非常优秀的团队提交的一个程序作业,居然连编译都没通過我找他们来谈话,他们发誓用好几个测试案例仔细的测试了程序当然了,他们和我用的是同一台机器完全相同的环境,都是在那囼大型机上这个神秘事件只到几周后才搞明白。原来机器上的 Pascal 编译器被升级了升级刚好发生在学生完成任务和我开始批改作业之间。怹们的程序有一个很小的词法错误(如果记得没错是多了个分号),而老的编译器没有检测到!

我要回帖

更多关于 生物组成的方式从简单到复杂 的文章

 

随机推荐