虽然Perl可能不像以前那么流行了, 许多动态语言和网络技术,比如JavaScript, PHP, Python, 和ruby——都受到了Perl的影响. 您仍然可以看到30年前在Perl中做出的设计决策在今天的这些语言中仍然存在.
最初由创作者拉里·沃尔在20世纪80年代末发布, Perl在正确的时间出现在正确的地方,并迅速成为internet开发中的主要参与者. 作为最早的动态类型语言之一, 它为开发人员提供了快速完成以前无法完成的任务的工具. 他们不再需要预先分配内存或跟踪变量存储的数据类型.
Perl仍然是使用正则表达式进行文本处理的最佳编程语言之一, 这使得它非常容易用于处理文件输入和输出. Perl也常用于系统管理, web services, 数据库设计采用MySQL和Oracle数据库, 开源和shell脚本项目. 许多开发人员选择Perl而不是ASP.NET,因为它有很多库,它是开源的,功能强大. Also, Perl爱好者使用它而不是Bash和Unix Shell, 因为你既可以编写短程序,也可以编写大型分布式应用程序, 而在BASH或其他Unix shell中编写大型应用程序是相当困难的.
如果您正在寻找Perl开发人员, 这可能是因为您有一个遗留的Perl应用程序,或者您希望利用其正则表达式引擎的强大功能. 本招聘指南涵盖了基本的, 每个Perl程序员都应该彻底了解的关键方面.
References
As mentioned before, Perl编程带来了编程的重大转变,预示着从静态类型语言到动态类型语言的演变. 它带来的另一个变化是引用的使用方式. 指针的概念, 在C和c++等前身语言中很常见, 是否让许多开发者感到困惑, 所以Perl去掉了指针,引入了引用, 哪一个简化了开发人员的内存管理.
引用在Perl代码中被频繁而广泛地使用. 对于Perl web开发人员来说,理解它们非常重要, 因为元素访问的语法会根据是引用还是直接访问而变化.
问:在Perl中,如何初始化以下内容?
-
an array
-
an array reference
-
A hash
-
A hash reference
Furthermore, 如何将数组更改为数组引用, 一个散列到一个散列引用, and vice versa? 如何从这些变量中访问元素?
答:对于任何有经验的Perl开发人员来说,使用散列和数组引用都是一个非常基本的概念, 但是它可能会在语法上绊倒一些较新的Perl开发人员或从未真正掌握底层基础的开发人员.
初始化数组:
my @arr = (0, 1, 2);
初始化数组 @
前缀在变量名前面的符号, which denotes the variable type as an array; its elements are placed in parentheses.
初始化数组引用:
$arr_ref = [0,1,2];
对于数组引用,使用 $
符号,表示“标量”,元素放在方括号中. 引用没有指定为数组, just as a scalar, 因此,您必须小心地适当处理变量类型.
对于散列,语法是类似的.
Initializing a Hash:
my %hash = (0 => 'First', 1 => 'Second', 2 => 'Third');
Just as with an array, 散列的元素用圆括号定义, 但是由于变量是哈希值, it’s prefixed with a %
.
初始化数组引用:
my $hash_ref = {0 => 'First', 1 => 'Second', 2 => 'Third'};
与数组引用一样,散列引用变量的前缀是 $
,但是元素被放在花括号中.
引用散列或数组
引用数组或散列非常简单. 在Perl中,变量前面的反斜杠将返回对该变量的引用. 您应该期待类似以下的内容:
my $arr_ref = \@arr;
$hash_ref = \%哈希;
Dereferencing
解引用一个被引用的变量就像用适当的变量标识符重新赋值它一样简单. 例如,下面是你如何解引用数组和散列:
my @arr = @$arr_ref;
My %hash = %$hash_ref;
Accessing Elements
访问这些变量类型的元素和它们的参考版本之间的差异是业余开发人员可能会遇到的另一个问题.
#访问数组中的元素
我的$element = $arr[0];
注意,对于数组,您没有使用 @
prefix but rather the $
表示标量,这是访问数组的任何元素时返回的类型. 访问数组引用、散列和散列引用的元素遵循类似的语法:
#访问数组引用中的元素
$element = ${$array_ref}[0];
#访问散列中的一个元素
$element = $hash{0};
#访问哈希引用中的一个元素
my $element = $hash_ref->{0};
Special Variables
Perl的独特之处在于它提供的特殊变量的数量. 虽然这可以使Perl代码非常简洁,但对新开发人员来说也相当晦涩. 而只有具有Perl专业知识的人才会知道大多数(或全部)特殊变量, 每个Perl开发人员都有一些关键的特性, 无论技能水平如何, 应该熟悉.
Q: Using $_
口头解释以下示例代码片段的功能:
@new = map {$_ + 1} @values;
A: The map
函数将遍历数组中的每个元素 @values
array and $_
将被设置为每个迭代的元素. 这相当于以下更常见和详细的代码:
my @new = ();
foreach (@values) {
push(@new, $_ + 1);
}
or
my @new = ();
Foreach $value (@values) {
push(@new, $value + 1);
}
Q: Using @_
在下面的例程中,解释的值 @_
:
sub my_subroutine {}
A: @_
将被设置为传递给子例程的任何参数.
因此,例如,如果子程序被调用如下:
my_suboutine (1, 'string', 2);
…then @_
将是一个包含元素的数组 (1, 'string', 2)
.
Regular Expressions
Perl提供了一种强大而简单的方法来处理正则表达式. 即使开发人员不做文本处理, 毫无疑问,他们会在Perl中遇到正则表达式最适合的情况.
问:请详细解释以下代码的作用:
$str =~ s/-//g;
答:它会删除所有连字符(-
字符)从字符串.
这里有一个变量 $str
它包含一个字符串.
The =~
Perl操作符是用来执行正则表达式的吗.
The s
左边表示我们要做一个替换.
The slashes after the s
分别界定要匹配的正则表达式模式及其替换. 斜杠之后是任何可选的修饰符. 让我们一块一块地把它拆开:
In this example, -
匹配所有连字符.
第二组斜杠, //
,为空,因此第一部分中匹配的连字符将被替换为空(i.e., deleted.)
The g
is a modifier telling the regular expression engine to execute this globally on the string; without the g
修饰符,则只删除第一个连字符.
Q:编写一个脚本,将文件名列表作为命令行参数. 它的处理将获取这些错误日志文件,并计算在特定日期发生了多少错误.
对于以YYYY-MM-DD格式的时间戳开头的任何行, 增加当天的计数器并打印摘要, 按日期升序排列, like the following:
Example output:
2016-06-01: 3
2016-06-02: 4
2016-06-04: 1
没有出现在日志文件中的日期不需要出现在输出中.
答:一个简明的答案如下:
my %counts = ();
while (<>) {
If (/^(\d{4}-\d{2}-\d{2})/) {
$counts{$1}++;
}
}
对于(sort {$a CMP $b}键%计数){
打印“$_:$counts{$_}\n”;
}
菱形算子(<>
)是Perl中特殊操作符的另一个例子. 它将循环通过 @ARGV
array, 这些是传递给脚本的参数(在本例中是文件名), open the files, 把台词读一遍.
The if
语句包含一个正则表达式,该正则表达式隐式地检查 $_
特殊变量和while循环集 $_
在每一行中循环. In Perl, the $_
通常可以推断,这是一个这样的情况吗.
正则表达式本身正在做以下事情:
The caret ^
字符是否用于表示一行的开始, 这意味着匹配必须从一行的开头开始.
在正则表达式中使用括号时, 与括号内正则表达式部分匹配的字符串部分将被“捕获”(i.e.(存储在临时变量中). 正则表达式中可以有多个括号. 与第一组括号匹配的字符串部分将存储在临时变量中 $1
,第二个将存储在 $2
, and so on. 在上面的例子中,只有一组括号,所以 $1
会被安排参加那场比赛吗.
我们要查的匹配 \d{4}-\d{2}-\d{2}
, 由4位数字和破折号组成, followed by 2 digits, followed by a dash, 最后跟两个数字.
如果找到匹配项,则增加 %counts
按1散列,其中键是匹配的日期. 我们不需要在第一次找到键时初始化值,因为Perl会自动将值设置为0, 所以我们可以简单地用 ++
操作符为日期增加计数器.
In Perl, you don't have to set a value the first time you use a key in a hash; Perl automatically sets this value to 0, 因此,您可以使用' ++ '操作符来自增.
In the for
表述,我们再一次使用 $_
通过不显式地为每个循环命名值来特殊变量. 从右边开始:
-
The keys %counts
语句返回来自散列的键的数组. 这些将是我们之前遇到的日期.
-
The sort
函数遍历键数组并使用字符串比较函数 cmp
按升序对数组进行排序.
-
方法中使用生成的数组 for
循环,其中输出带有日期,后跟一个冒号. 类中访问该值 %counts
日期的哈希值(记录错误的次数),并将其追加,后面加一行.
Common Functions
与大多数现代编程语言一样,散列和数组是Perl编程的重要组成部分. 软件开发人员可能会发现数据存储在一种或另一种结构中, 但可能需要以特定格式检索它. Perl provides very concise and powerful functions to do this retrieval; functions with which experienced Perl developers must be familiar.
这些问题旨在测试应试者对常见Perl函数的熟悉程度. 合格的候选人应该了解常见的功能,如 map
and grep
. 如果应试者用一个函数解决了问题, 让他们用另一个函数来解.
初级程序员可能会编写代码创建一个单独的数组,然后使用' for '循环将值添加到散列中.
问:给定一个数组,你如何得到一个只有唯一元素的数组?
A:标准技术如下:
my %uniq_hash = map { $_ => 1 } @input;
@uniq = keys %uniq_hash;
给你 @input
array, and using map
的值来创建一个散列 @input
. 因为散列只允许唯一的键,所以不会有重复的键. 要返回一个数组,只需使用 keys
函数以数组形式获取哈希的键.
Q:编写一些代码,打印' yes ',如果值 3
is in an array.
A:你可以使用与上面相同的程序,然后简单地做:
my %uniq_hash = map { $_ => 1 } @input;
if ($uniq_hash{3}) { print 'yes'; }
这只是检查您创建的散列,看看是否有一个键被设置为3和, if there is, prints “yes”.
也可以达到同样的效果 grep
,它循环穿过 @input
数组并根据语句测试每个值,如下所示:
if (grep $_ eq 3, @input) { print 'yes'; }
两种方法都可行, 如果需要检查多个值以避免多次循环遍历数组,那么开发人员最好使用第一种技术. For a one-off check, though, 这不是问题, 在这种情况下,两种方法都是可以接受的.
A:虽然答案只有一行,但这个问题测试的是考生理解文章内容的能力 split
函数以及如何在Perl中将数组转换为哈希值:
my %hash = split /[=&]/, $str;
The function split
接受输入字符串,并在匹配出现的地方将其分割成一个数组(在本例中是等号或&号). 在本例中,结果数组将是 [key1, value1, key2, value2, key3, value3]
.
Perl将数组转换为散列,方法是将第一个元素作为键,将第二个元素作为值, 然后第三个作为键,第四个作为值,以此类推.
将split函数的结果存储为哈希类型,您将得到以下结果:
{
key1 => value1,
key2 => value2,
key3 => value3
}
做这件事的方法不止一种
Perl以提供多种方法来完成相同的软件开发而自豪, web development, 或者其他编程任务,比如在谷歌的移动操作系统中, Android, 可以在其上安装Perl 5. In front-end projects, Perl以方便使用脚本创建网站或将其部分嵌入WordPress或HTML而闻名, CSS, Node.js. 因此,对候选人的回答要保持开放的心态. 试着理解他们的做法背后的原因.
美国或国外的一些高级候选人可能完全掌握了用Perl进行编程和应用程序开发的简明方法,但为了更容易阅读,他们选择以更详细的方式编写代码. 这些开发者可能, for example, 积极避免使用特殊的$_变量,因为它需要花费时间来弄清楚它实际指的是什么. 因此,它们可能会选择使用命名变量. 另一种选择可能是一个对语言有很强掌握的开发人员, 但是他写的代码是初级开发人员无法读懂的.
通过花时间去理解答案背后的想法, 您将深入了解候选人的思维过程,并找到那些理解他们编写的代码的长期含义的人.