回复: 10
跳转到指定楼层
上一主题 下一主题
收起左侧

无人车公司C++面试题 (求讨论)

全局:

2017(10-12月) 码农类General 硕士 全职@start up - 网上海投 - 技术电面  | | Fail | 在职跳槽

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
挂在这轮C++面试上了,求elegant的solution。 我后来调出了用inheritance和vector<std::function>的方法,但都感觉不够好。大家讨论讨论。。。
/*
We are working on a batch image processing pipeline. We want to be able to list
the operations to be applied on all the images (and their parameters) in a
config file. For example:

ConvertToGrayScale
Blur 3.
Resize 256 256
BlendWith

The idea is to load the config file, create the pipeline, and process all the
images through the pipeline. We have access to a library for image manipulation
that has all the functions that we need for those operations.

How would you design such a pipeline?
This is intentionally vague, so part of the exercise is to define the scope.
Keep in mind that you have 30 minutes, so you are encouraged to first go for
a decently simple solution, and then discuss extensions.

In this case we will mock the behavior because we don't have IO, so basically
it should print:

one: Converting to gray scale
one: Blurring with factor 3
one: Resizing img with x = 256 and y = 256
one: Blending with
您好!
本帖隐藏的内容需要积分高于 188 才可浏览
您当前积分为 0。
使用VIP即刻解锁阅读权限或查看其他获取积分的方式
游客,您好!
本帖隐藏的内容需要积分高于 188 才可浏览
您当前积分为 0。
VIP即刻解锁阅读权限查看其他获取积分的方式
Unlock interview details and practice with AI
Curated Interview Questions from Top Companies
main() {

// Read the config file
vector<string> cmds = { "ConvertToGrayScale",
"Blur 3.",
"Resize 256 256",
"BlendWith " };

vector<Image> imgs = { Image("one"),
Image("two"),
Image("three") };

// Your work goes here


return 0;
}

评分

参与人数 2大米 +33 收起 理由
匿名用户-8LUAW + 30
Z君 + 3 谢谢大神的代码参考,学习了!

查看全部评分


上一篇:活坡 实习 OA
下一篇:脸书面经 电面+onsite+加面

本帖被以下淘专辑推荐:

  • · Cruise|主题: 12, 订阅: 0
推荐
magicsets 2017-12-4 08:20:35 | 只看该作者
全局:
我觉得这个题目主要有两个注意点:
(1) 效率
(2) 可扩展性 (extensibility)

效率就是在创建pipeline时把能做的预处理都做了(主要是parse那些参数),这样你使用同一个pipeline处理不同的image的时候就不用做重复工作。

可扩展性就是说如果我们想要添加一个新的operation,只需要修改代码中很少的地方,而不是要东改一点西改一点。也就是说,代码要有低耦合度(low coupling)

下面是一份参考代码——在这一实现中,如果要添加一个新的operation,那么不用修改已有代码,只要
(1) 继承并实现ImageTransformationHandle / ImageTransformationFunction规定的接口
(2) 用一行代码注册该operation:ImageTransformationPipeline::RegisterFunction<...>()

  1. #include <algorithm>
  2. #include <iostream>
  3. #include <memory>
  4. #include <sstream>
  5. #include <stdexcept>
  6. #include <string>
  7. #include <unordered_map>
  8. #include <vector>

  9. // Mock image class
  10. class Image {
  11. public:
  12.   Image(const std::string &name) : name_(name) {}

  13.   const std::string& name() const { return name_; }

  14. private:
  15.   const std::string name_;
  16. };

  17. // Sample image manipulation library.
  18. namespace ImgLib {

  19. void convertToGrayScale(Image & img) {
  20.   std::cout << img.name() << ": Converting to gray scale" << std::endl;
  21. }

  22. void blur(Image & img, float factor) {
  23.   std::cout << img.name() << ": Blurring with factor " << factor << std::endl;
  24. }

  25. void resize(Image & img, int x, int y) {
  26.   std::cout << img.name() << ": Resizing img with x = " << x << " and y = " << y << std::endl;
  27. }

  28. void blend(Image & img, const Image& other) {
  29.   std::cout << img.name() << ": Blending with " << other.name() << std::endl;
  30. }

  31. /* Potentially many more! */

  32. } // namespace ImgLib

  33. ////////////////////////////////////////////////////////////////////////////////
  34. /////////////////////////////// Pipeline 组件抽象 ///////////////////////////////
  35. ////////////////////////////////////////////////////////////////////////////////
  36. class ImageTransformationHandle {
  37. public:
  38.   virtual void transform(Image &image) const = 0;
  39. };

  40. class ImageTransformationFunction {
  41. public:
  42.   virtual std::string getName() const = 0;
  43.   virtual ImageTransformationHandle* generateHandle(std::istringstream &params) const = 0;
  44. };

  45. ////////////////////////////////////////////////////////////////////////////////
  46. ////////////////////////////////// Pipeline ////////////////////////////////////
  47. ////////////////////////////////////////////////////////////////////////////////
  48. class ImageTransformationPipeline {
  49. public:
  50.   ImageTransformationPipeline(const std::vector<std::string> &cmds) {
  51.     for (const std::string &cmd : cmds) {
  52.       std::istringstream iss(cmd);
  53.       std::string fname;
  54.       iss >> fname;
  55.       ImageTransformationFunction *func = FindFunction(fname);
  56.       if (func == nullptr) {
  57.         throw std::runtime_error("Invalid image transformation");
  58.       }
  59.       pipeline_.emplace_back(func->generateHandle(iss));
  60.     }
  61.   }

  62.   void transform(Image &image) {
  63.     for (const auto &handle : pipeline_) {
  64.       handle->transform(image);
  65.     }
  66.   }

  67.   void transform(std::vector<Image> &images) {
  68.     for (Image &image : images) {
  69.       transform(image);
  70.     }
  71.   }

  72. private:
  73.   std::vector<std::unique_ptr<ImageTransformationHandle>> pipeline_;

  74.   // 为了简便把function resolving写在这里,其实最好再写一个class ImageTransformationFactory
  75.   static std::unordered_map<
  76.       std::string, std::unique_ptr<ImageTransformationFunction>> functions_;

  77.   static ImageTransformationFunction* FindFunction(const std::string &name) {
  78.     auto it = functions_.find(ToLowerCase(name));
  79.     if (it == functions_.end()) {
  80.       return nullptr;
  81.     } else {
  82.       return it->second.get();
  83.     }
  84.   }

  85.   static std::string ToLowerCase(const std::string &str) {
  86.     std::string ret(str.size(), ' ');
  87.     std::transform(str.begin(), str.end(), ret.begin(), tolower);
  88.     return ret;
  89.   }

  90. public:
  91.   template <typename Function>
  92.   static void RegisterFunction() {
  93.     Function *function = new Function();
  94.     functions_.emplace(ToLowerCase(function->getName()), function);
  95.   }
  96. };

  97. std::unordered_map<std::string, std::unique_ptr<ImageTransformationFunction>>
  98.     ImageTransformationPipeline::functions_;

  99. ////////////////////////////////////////////////////////////////////////////////
  100. /////////////////////////// Pipeline 各个组件的实现 //////////////////////////////
  101. ////////////////////////////////////////////////////////////////////////////////

  102. // Convert to gray scale.
  103. class ConvertToGrayScaleHandle : public ImageTransformationHandle {
  104. public:
  105.   void transform(Image &image) const override {
  106.     ImgLib::convertToGrayScale(image);
  107.   }
  108. };
  109. class ConvertToGrayScaleFunction : public ImageTransformationFunction {
  110. public:
  111.   std::string getName() const override {
  112.     return "ConvertToGrayScale";
  113.   }
  114.   ImageTransformationHandle* generateHandle(std::istringstream &params) const override {
  115.     return new ConvertToGrayScaleHandle();
  116.   }
  117. };

  118. // Blur.
  119. class BlurHandle : public ImageTransformationHandle {
  120. public:
  121.   BlurHandle(const float factor) : factor_(factor) {}

  122.   void transform(Image &image) const override {
  123.     ImgLib::blur(image, factor_);
  124.   }
  125. private:
  126.   const float factor_;
  127. };
  128. class BlurFunction : public ImageTransformationFunction {
  129. public:
  130.   std::string getName() const override {
  131.     return "Blur";
  132.   }
  133.   ImageTransformationHandle* generateHandle(std::istringstream &params) const override {
  134.     float factor;
  135.     params >> factor;
  136.     return new BlurHandle(factor);
  137.   }
  138. };

  139. // Resize.
  140. class ResizeHandle : public ImageTransformationHandle {
  141. public:
  142.   ResizeHandle(const int x, const int y) : x_(x), y_(y) {}

  143.   void transform(Image &image) const override {
  144.     ImgLib::resize(image, x_, y_);
  145.   }
  146. private:
  147.   const int x_;
  148.   const int y_;
  149. };
  150. class ResizeFunction : public ImageTransformationFunction {
  151. public:
  152.   std::string getName() const override {
  153.     return "Resize";
  154.   }
  155.   ImageTransformationHandle* generateHandle(std::istringstream &params) const override {
  156.     int x, y;
  157.     params >> x >> y;
  158.     return new ResizeHandle(x, y);
  159.   }
  160. };

  161. // Blend.
  162. class BlendWithHandle : public ImageTransformationHandle {
  163. public:
  164.   BlendWithHandle(const std::string &url) : other_(url) {}

  165.   void transform(Image &image) const override {
  166.     ImgLib::blend(image, other_);
  167.   }
  168. private:
  169.   const Image other_;
  170. };
  171. class BlendWithFunction : public ImageTransformationFunction {
  172. public:
  173.   std::string getName() const override {
  174.     return "BlendWith";
  175.   }
  176.   ImageTransformationHandle* generateHandle(std::istringstream &params) const override {
  177.     std::string url;
  178.     params >> url;
  179.     return new BlendWithHandle(url);
  180.   }
  181. };


  182. int main() {
  183.   // Read the config file
  184.   std::vector<std::string> cmds = {
  185.       "ConvertToGrayScale",
  186.       "Blur 3.",
  187.       "Resize 256 256",
  188.       "BlendWith http://www.solstation.com/stars/earth3au.jpg"
  189.   };

  190.   std::vector<Image> imgs = {
  191.       Image("one"), Image("two"), Image("three")
  192.   };

  193.   // Your work goes here.

  194.   // Register transformations.
  195.   ImageTransformationPipeline::RegisterFunction<ConvertToGrayScaleFunction>();
  196.   ImageTransformationPipeline::RegisterFunction<BlurFunction>();
  197.   ImageTransformationPipeline::RegisterFunction<ResizeFunction>();
  198.   ImageTransformationPipeline::RegisterFunction<BlendWithFunction>();

  199.   // Construct a pipeline instance from the commands.
  200.   ImageTransformationPipeline pipeline(cmds);

  201.   // Apply the transformations to imgs.
  202.   pipeline.transform(imgs);

  203.   return 0;
  204. }
复制代码

评分

参与人数 2大米 +42 收起 理由
crazybadboy + 2 很有用的信息!
匿名用户-8LUAW + 40

查看全部评分

回复

使用道具 举报

🔗
 楼主| foreverzad 2017-12-4 08:43:44 | 只看该作者
全局:
太牛了~~这个C++功底深厚啊~~,还没看完但感觉满足了面试官所有的要求~
回复

使用道具 举报

🔗
 楼主| foreverzad 2017-12-4 13:45:33 | 只看该作者
全局:
好像compile 报错了。。/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/unordered_map:546:11: error:
      no matching constructor for initialization of 'value_type' (aka 'pair<const key_type,
      mapped_type>')
        : __cc(std::forward<_Args>(__args)...) {}
          ^    ~~~~~~~~~~~~~~~~~~~~~~~~~~~
回复

使用道具 举报

🔗
snmnmin 2017-12-4 14:19:39 | 只看该作者
全局:
哇,你把这个贴出来来,我面这个题目时完全不知道怎么下手啊,顿时感觉C++学的太烂了,要仔细学习下答案。
回复

使用道具 举报

🔗
magicsets 2017-12-4 14:28:58 | 只看该作者
全局:
foreverzad 发表于 2017-12-4 13:45
好像compile 报错了。。/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain ...

编译时加上-std=c++14,然后试试第114行改成:

  1.     functions_.emplace(ToLowerCase(function->getName()),
  2.                        std::unique_ptr<Function>(function));
复制代码
(从报错信息上来看似乎是这行代码问题,你可以把整个stack贴出来)

我也是用的xcode,可以编译通过的...
回复

使用道具 举报

🔗
 楼主| foreverzad 2017-12-4 15:24:00 | 只看该作者
全局:
snmnmin 发表于 2017-12-4 14:19
哇,你把这个贴出来来,我面这个题目时完全不知道怎么下手啊,顿时感觉C++学的太烂了,要仔细学习下答案。

momo,我也挂了~~你最后去做无人车了吗?
回复

使用道具 举报

🔗
 楼主| foreverzad 2017-12-4 15:24:45 | 只看该作者
全局:
magicsets 发表于 2017-12-4 14:28
编译时加上-std=c++14,然后试试第114行改成:(从报错信息上来看似乎是这行代码问题,你可以把整个stack ...

ok,谢谢啊,我回头再试试~~xcode我用得不多。。。所以不熟~~
回复

使用道具 举报

🔗
bearjoe 2018-1-8 15:04:44 | 只看该作者
全局:
aimotive, yaml file
回复

使用道具 举报

🔗
bearjoe 2018-1-8 15:21:59 | 只看该作者
全局:
or autosar manifest load
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表