我遇到过的最好的工程面试问题,第 1 部分 – Arthur O’Dwyer – 主要是关于 C++ 的内容

我已经有一段时间没有接受软件工程面试了。 但我仍然记得我最喜欢的面试问题。 那是在 2013 年左右的 MemSQL 会议上。(他们 甚至没有保留他们的名字,所以我认为他们不再依赖这个特定的面试问题。 我并不因为揭露它而感到难过。 这是一个很棒的故事,我给人们讲过很多次; 我以前从未写过博客。)

好的,所以这本身不是一个“问题”;而是一个“问题”。 这是一个编程挑战。 我忘记了他们为此付出了多少时间。 假设三个小时,算上解释问题的时间。

由于 MemSQL 是一家数据库公司,因此这是一个数据库挑战。

介绍内存缓存

你知道 memcached? 不? 嗯,它是内存中的键值存储。 (请在此处阅读其“关于”页面。)让我们下载它的代码并构建它,以便我可以向您展示它的作用。

您可能需要 brew install libevent 也许还需要一些其他东西才能成功构建 memcached。 弄清楚这一点并不会太困难; 但无论如何,与环境的争论并不是测试的一部分。 您可以假设受访者已经获得了访问 Linux 机器的权限,并且所有正确的依赖项都已就位。

为了获得真实的 2013 年体验,让我们绕过 GitHub 仓库
并解压当代源代码发行版:

curl -O https://memcached.org/files/memcached-1.4.15.tar.gz
tar zxvf memcached-1.4.15.tar.gz
cd memcached-1.4.15
./configure
make

现在我们已经构建了 memcached 可执行的。 让我们开始运行:

我们可以通过默认的memcached端口11211与服务器通信。它的协议基本上是纯文本,所以我们可以使用普通的旧协议 telnet
与它交谈。 (如果你没有 telnet 不再,替换单词 nc -c 为了 telnet.)

$ telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

玩转 memcached

memcached 是一个键值存储。 这意味着我们可以告诉它记住一些东西(键和值之间的关联),然后再次请求该键,它会告诉我们它记住的值。 在 memcached 中,键始终是 ASCII 字符串,值始终是任意字节流(这意味着您必须手动指定它们的长度)。 例如,在您的 telnet 会话中输入以下内容:

set fullname 0 3600 10
John Smith

这告诉 memcached 记住字符串键之间的关联 fullname
和 10 字节值 John Smith。 该行上的其他数字是“标志”值(0)与字节流值一起记住; 和过期超时(3600)以秒为单位,之后 memcached 将忘记此关联。 不管怎样,当你输入这两行之后,memcached 将会响应:

现在您可以检索值 fullname 通过在同一个 telnet 会话中输入:

memcached 将响应:

VALUE fullname 0 10
John Smith
END

您可以覆盖与关联的值 fullname 通过发行另一个
set fullname 命令。 您还可以要求memcached以某些方式修改该值; 例如,有专门的命令 appendprepend

append fullname 0 3600 6
-Jones
STORED
get fullname
VALUE fullname 0 16
John Smith-Jones
END

当然如果你想追加 -Jonesfullname 从客户端程序中,您 可以 做这样的事情:

# pip install python-memcached
import memcache
mc = memcache.Client(['127.0.0.1:11211'])
v = mc.get('fullname')    # get the old value from memcached
v += '-Jones'             # append -Jones
mc.set('fullname', v)     # set the new value into memcached

但是memcached的专用优势 append 命令是保证执行的 原子地。 如果您有多个客户端连接到同一个 memcached 服务器,并且它们都尝试同时附加到同一个密钥,则
get/set 版本可能会导致其中一些更新丢失,而 append
你放心,他们都会被查到的。

另一个以原子方式执行的专用命令是 incr

set age 0 3600 2
37
STORED
incr age 1

memcached 以后增量值响应:

由于存在多个客户端,此响应很有用。 如果您单独发出
get age 命令,您可能只有在其他几个客户端完成自己的更新后才能看到新值。 如果您打算将该值用作序列号、SQL 主键或类似的东西,那么有一种方法可以查看递增的值,这是非常好的 原子地

当然,memcached 也会记住增加的值:

get age
VALUE age 0 2
38
END

请注意 3738 仍然以字节串的形式存储和返回; 它们作为原子操作的一部分从 ASCII 解码为整数,然后再解码回来。 如果你尝试 incr 一个非整数值,你会得到一个错误:

incr fullname 1
CLIENT_ERROR cannot increment or decrement non-numeric value

最后,请注意 incr 是一个成熟的加法运算:您可以递增(或 decr)通过任何正值,而不仅仅是通过 1

incr age 10
48
decr age 10
38
incr age -1
CLIENT_ERROR invalid numeric delta argument

顺便说一句,当您与 memcached 通信完毕并想要终止连接时,您可以键入 memcached 命令 quit。 (如果您正在使用 nc -c, Ctrl+D 也有效。 或者,只需转到终端窗口 memcached 服务器正在运行,请按 Ctrl+C 将其关闭。)

挑战:修改 memcached

通过其 incrdecr 命令,memcached 提供了一种内置方法来原子地将 (k) 添加到数字上。 但它不提供其他算术运算; 特别是,不存在“原子乘以(k)”运算。

您的编程挑战: 添加一个 mult 命令到 memcached。

完成后,我应该能够远程登录到您的 memcached 客户端并运行如下命令

你有三个小时的时间。 去!


剧透及分析请参见
“我遇到过的最好的工程面试问题,第 2 部分。”

1711375950
#我遇到过的最好的工程面试问题第 #部分 #Arthur #ODwyer #主要是关于 #的内容
2024-03-25 05:28:28

Leave a Reply

Your email address will not be published. Required fields are marked *

近期新闻​

编辑精选​