我从工作面试中学到的关于 C# 的知识

原文链接:https://michaelscodingspot.com/what-i-learned-about-c-from-job-interviews/

作者:Michael Shpilt

我最近参加了一些最大的科技公司的一系列工作面试。在没有透露姓名的情况下,我得到了世界排名前 5 的科技公司中的 3 家的面试机会。你知道我在说谁。

这些公司的面试流程大不相同,但也有很多共同点,包括对编码问题的高度重视。这些问题可能是对某些东西进行排序,打印所有可能的组合,或者找到走出迷宫的路。我不确定解决这些问题与实际软件开发有何关系,但这些公司似乎确实这么认为。我不记得在我的日常工作中必须实现排序算法。或者反转链表。或者在图形上使用 DFS。尽管如此,您仍然可以证明能够解决这些问题的开发人员在现实生活中会更好。

但这篇文章不是关于这些问题的动机。这篇文章是关于我从求职面试中学到的关于 C# 的知识。具体来说,从编码问题。我已经使用 C# 进行专业编程 10 多年了,但正如我发现的那样,开发软件与通过面试完全不同。

顺便说一下,所有大公司(译者注:仅限于西雅图)都允许候选人用任何编程语言解决问题。因此,即使该职位是针对 JavaScript 的,您仍然可以编写 C# 代码。

多维数组

我认为我在工作中从未使用过多维数组。当然,我有时会使用一个列表列表List<List<T>>,可能还会使用一个数组列表List<int[]>,以及偶尔使用数组字典列表List<Dictionary<int, string[]>>(这个不常用)。没有那么多多维数组。但我发现它们在编码练习中非常有用。

多维数组与数组数组不同,例如int[][] arr(锯齿状数组)。后者是一组数组,其中每个数组的长度可以不同。而多维数组更适合常见问题,例如表示 2D 迷宫或 3D 立方体。如果您很快就要参加工作面试,请更新这些语法。这包括初始值设定项、维度长度和列/行各自的索引。

int[,] arr = new int[3, 2]{{1, 2},{3, 4},{5, 6}};int firstDimensionLength = arr.GetLength(0);//3
int secondDimensionLength = arr.GetLength(1);//2
var p00 = arr[0, 0];//1
var p01 = arr[0, 1];//2
var p10 = arr[1, 0];//3

这是一个多维数组派上用场的问题示例:

给定一个由 MxN 方形单元组成的二维空间,其中每个单元要么是一个自由空间,要么是一面墙,找到自由空间的最大连通区域并返回其单元数。

使用元组,而不是类

我已经用 C# 编程一段时间了,我很少使用元组。可能是因为我不习惯ValueTuple. 我的默认选择通常是一个类。对于类有一些好处:它们使代码更加结构化并且可以说更具可读性。但是元组实际上有一个非常好的语法。也许,更重要的是,它们具有更

紧凑的

语法。只是少写了。如果你想改变一些东西,那就没有什么可改变的了。这些事情在编码面试中非常重要。您希望花费最少的时间输入代码,以便有更多的时间思考。并可能回答更多问题。

这是一个例子。假设我有一个方法可以返回 3D 数组中的一个点,当我使用一个类时,我会这样写:

class Point3D
{public int X { get; set; }public int Y { get; set; }public int Z { get; set; }
}private Point3D Calc(){ ... }

而对于元组,它是:

private (int X, int Y, int Z) Calc(){ ... }

请记住,在编码面试中,您将在一种类似于在线记事本的环境中进行写作,在那里您没有代码片段、自动完成功能以及您习惯于从 Visual Studio 使用的所有其他优点。

二元运算也是一回事

您在库和应用程序中使用<<>>&|运算符的频率如何?我猜没有那么多。我也没有,但它们在编码问题中很有用。这里有一个小提醒:

int a = 15;
Console.WriteLine(Convert.ToString(a, toBase: 2));//1111
a = a >> 2;//shift right twice (same as divide by 4)
Console.WriteLine(Convert.ToString(a, toBase: 2));//11
a = a << 3;//shift left 3 times (same as multiply by 8)
Console.WriteLine(Convert.ToString(a, toBase: 2));//11000
a = a & 0b_11111; // stays same
Console.WriteLine(Convert.ToString(a, toBase: 2));//11000
a = a & 0b_1111; // remains 1000 because leftmost digit is nullified
Console.WriteLine(Convert.ToString(a, toBase: 2));//1000
a = a | 0b_1; // becomes 1001
Console.WriteLine(Convert.ToString(a, toBase: 2));//1001
a = a | 0b_110; // becomes 1111
Console.WriteLine(Convert.ToString(a, toBase: 2));//111

关于二进制的一件事是,以基数 2 进行迭代可能有助于解决置换问题。例如,考虑以下问题:

给定一组项目,打印出这些项目的所有可能组合,其中每个项目可能包含或不包含。顺序无关紧要。

因此对于输入 [“a”,”b”,”c”],输出将是:

[empty array], a, b, c, ab, ac, bc, abc

现在考虑从 0 到 2^3 的二进制迭代。如果每个数字都描述了结果中是否包含数组的一个项目,那么这是打印出所有可能迭代的一种方法。上面的结果可以描述为:

1
2
000, 001, 010, 100, 110, 101, 011, 111

不要只依赖二元运算符。解决这个置换问题的另一种方法是使用简单的递归。

字符串和数组的有用内容

编码问题中使用的大多数方法与现实生活中使用的方法相同。对于字符串,它是您的.Substring.Contains.Replacestring.Equals().ToLower().ToUpper(), 等。我发现在这些问题中非常有用的一种方法是string.Join. 它将加入一个字符串集合,每对字符串之间有一个分隔符。例如:

var joined = string.Join(",", new[] { "a", "b", "c" }); // "a,b,c"

对于数组,我还发现了一些有用的方法。其中之一是Array.Sort,它可以接受Comparison<T>委托来根据您的需要进行排序。假设您想根据最后一个字母对一堆字符串进行排序。这很简单:

var words = new[] { "cat", "job", "zebra", "row" };
Array.Sort(words, (w1, w2) =>
{var lastLetter1 = w1[w1.Length - 1];var lastLetter2 = w2[w2.Length - 1];return lastLetter1 < lastLetter2 ? -1 : 1;// or: return lastLetter1.CompareTo(lastLetter2);
});
var joined = string.Join(',', words); // zebra,job,cat,row

我以前从未真正使用过的另一个有用的方法是Array.Copy. 除此之外,它还可以将数组的切片复制到新数组中。例如:

var words = new[] { "cat", "job", "zebra", "row" };
string[] dest = new string[2];
Array.Copy(words, sourceIndex:1, dest, destinationIndex: 0, length: 2);
Console.WriteLine(string.Join(',', dest)); // job, zebra

还有其他方法可以复制数组切片。其中之一是使用 LINQ: words.Skip(1).Take(2).ToArray()。但我不确定我是否会在与 Java 程序员的面试中展示我的 ninja C# 技能。

Python有时更简短

关于 C# 有很多好话要说,但它可能不是算法的最佳语言。我的意思是,Python 中的相同解决方案会更短,而且我敢说更干净。如果您有疑问,请访问leetcode.com[1]或任何其他类似站点,并浏览解决方案。尝试比较 C# 和 Python 中同一问题的解决方案。Python 的看起来不是更……漂亮吗?再说一次,也许是因为栅栏另一边的草总是很茂盛。

我学到的与 C# 无关的东西

你可以从求职面试中学到很多东西。既是面试官,又是被面试者。我在整个过程中学到的最重要的东西与 C# 或任何其他语言无关。由于这篇文章是关于编码挑战的,我将坚持我从这些方面学到的东西。以下是我学到的一些技巧和窍门,可以帮助我解决编码问题:

熟能生巧

面试的准备是一切的不同之处。是的,这需要很多时间,但考虑到风险,这是非常值得的。从严格的财务角度来看,在薪水高、资历高的公司工作,是您一生中最重要的财务改善之一。花几天或几周的时间为它们做准备绝对值得。

对于编码问题,我使用了leetcode.com[2],这是解决此类[3]问题的最佳网站之一。我建议从简单的问题开始,花最多的时间在中等,并尝试一些困难的问题。该站点的最佳功能之一是您可以在每个问题的讨论部分看到其他提交的内容。该网站非常受欢迎,所以总是有各种语言的提交。我建议您先尝试自己解决问题,然后再查看其他提交的内容(即使您成功了)。我当然从中学到了很多。

大多数问题都很简单

如果您浏览leetcode.com 之[4]类的网站[5],您可能会认为 Facebook 或 Apple 等顶级公司会问您非常棘手的[6]问题。根据我的经验,这不是真的。大多数问题都在中等难度范围内。不太容易,但也不难,绝对不难。许多问题都是递归 DFS 或 BFS 的经典实现。或者Bin 装箱问题[7]的变体。有时您需要遍历二叉树。在极少数情况下,您可能需要使用堆。

但是你也可能在简单和中等的问题上失败。相信我,我知道。面试压力很大。您必须非常迅速地提出解决方案。有时面试官会把你引向错误的方向(无论是有意还是无意)。其他时候,您可能会记住某些事情或分心,这会使您偏离正确(且简单)的解决方案。

我学会了始终牢记这个问题可能并不棘手,但很容易。这大多是真实的,思考可以减轻一些压力。

写之前想一想

在实际编写解决方案之前,请多想一想。它是最优化的吗?你能达到更好的时间复杂度吗?代码是否会简短易懂?问问自己是否可以改进解决方案。

通常,面试官会在实际编写之前要求您描述您的解决方案。这对你来说很棒。即使他们不问,我也建议你自己解释一下。解释完之后,写代码就容易多了。此外,您经常会在解决方案中发现一些问题。这也是与面试官建立联系的好机会。你可以向他们展示你的思维过程,证明你是一个聪明的人,很容易相处。

使用简称

在软件开发中,我们非常习惯于描述性的名称。所以我会有一个方法GetAddressandCalculateFastestRoute而不是Getand Calc。在编码问题中,恰恰相反的是要走的路。至少这对我有用。坚持为变量名称和方法使用短名称。如果你觉得你的面试官是一个固执的人,你可以在你的解决方案奏效后给他们重命名,或者只是提到你在这次面试中使用了简称,而不是常规。

我不是说要命名您的方法AB. 但我是说,如果您的问题是遍历迷宫,并且您使用的是深度优先搜索算法,请随意命名该方法DFS而不是FindAWayInAMaze.

总结

一家大企业面试是一种迷人的经历。这与为初创公司甚至大型科技公司接受面试完全不同。公司之间的面试有很大的不同,你可以了解一些公司文化。

我在这里谈到了编码问题,但这只是面试的一部分。大多数公司也有某种“系统设计”面试,你必须架构一个大型(通常是分布式)系统。面试过程的另一部分是关于你在组织中的行为、态度和行为。

你是团队成员吗?您是否总是为客户着想?你能独立工作吗?这些可能与技术问题一样重要。

References

[1] leetcode.com: https://leetcode.com/
[2] leetcode.com: https://leetcode.com/
[3] 此类: https://leetcode.com/
[4] leetcode.com 之: https://leetcode.com/
[5] 网站: https://leetcode.com/
[6] 棘手的: https://leetcode.com/
[7] Bin 装箱问题: https://en.wikipedia.org/wiki/Bin_packing_problem

我从大厂面试中学到的关于 C# 的知识相关推荐

  1. 大厂面试官在校招面试中爱问啥?

    如果你在简历中写了这句话,保证能拿到大厂面试机会:扎实的计算机基础,良好的数据结构与算法功底. 然后,你就会被问到头皮发麻. 虽然是段子,但也一定程度上说明了大厂非常注重计算机基础,也是真的喜欢问计算 ...

  2. 程序员大厂面试被怼:干这么多年只会增删改查!谁会要!

    大多数互联网的从业者都有一个梦想:进大厂. 因为不仅可以享受较好的福利待遇,也能与更优秀的人一起共事,获得更专业.更快速的成长. 相信无论是校招还是社招,面试过大厂的程序员似乎总会有种种困境: 毕业季 ...

  3. 【建议收藏】2020年中高级Android大厂面试秘籍,为你保驾护航金三银四,直通大厂(Android高级篇下)...

    前言 成为一名优秀的Android开发,需要一份完备的知识体系,在这里,让我们一起成长为自己所想的那样~. A awesome android expert interview questions a ...

  4. 互联网大厂面试官:推荐系统最经典的 排序模型 有哪些?你了解多少?

    互联网大厂面试官:推荐系统最经典的 排序模型 有哪些?你了解多少? 提示:最近系统性地学习推荐系统的课程.我们以小红书的场景为例,讲工业界的推荐系统. 我只讲工业界实际有用的技术.说实话,工业界的技术 ...

  5. 我是如何在天猫、蚂蚁金服、百度等大厂面试中被拒的 | 掘金技术征文

    本人16年毕业于普通二本院校网络相关专业,工作经验两年半,目前就职业于一家普通民营企业. 由于非985.211学历硬伤,校招进大厂的门槛远高于同届985.211的毕业生.于是乎,从毕业到现在经历了三家 ...

  6. 如何从菜鸡变成收割机,大厂面试的算法,你懂了吗?

    是什么?让大厂面试显得逼格很高,是算法和数据结构吗? 是的!!! Google工程师曾总结过,大厂之所以爱考察算法和数据结构是因为: 算法能力能够准确辨别一个程序员的技术功底是否扎实: 算法能力是发掘 ...

  7. 去大厂面试,说了没高并发经验,面试官还是抓着这个问!

    我真服了,我tm现在满脑子都是"高并发",不得不说这个词真是技术圈的一个高频词. 如果不拿出这个说道说道就感觉技术非常欠缺似的.不过确实,高并发几乎是每个程序员都想拥有的经验. 原 ...

  8. 只需 9.9 元!前 Facebook 工程师 7 天带你掌握 7 大数据结构,大厂面试必备!

    数据结构与算法是互联网大厂面试的敲门砖,也是开发者精益求精.持续提升的内功基础.工作中选择合适的数据结构,往往能达到事半功倍的效果.然而真正学习算法的时候,又是另外一番景象,因为真正基础.真正核心的东 ...

  9. 互联网大厂面试,谈索引就直逼这些底层?难的是我不懂这些原理

    01 为啥BAT大厂,在数据库上都喜欢深入的问索引呢? 一线大厂,是很多人梦寐以求的盛典天堂.因为存在的无限的可能,可以帮你实现自己的远大抱负.大平台机会.视野.格局往往都比小厂多很多.但随之而来也是 ...

最新文章

  1. 用栈、回溯算法设计迷宫程序
  2. 这份Kaggle Grandmaster的图像分类训练技巧,你知道多少?
  3. python编程语法-Python编程入门——基础语法详解(经典)
  4. 我的秋招之路(开篇)
  5. Sersync+Rsync 增量实时同步
  6. SQL性能优化案例分析
  7. 2019牛客多校第七场E Find the median 权值线段树+离散化
  8. Python词汇比较运算符
  9. 重学C---------第三节:求两个整数中的大者
  10. Android手机中第三方签名应用程序无法获得的permission
  11. mysql+分页脚本_MySql实现分页查询的SQL
  12. 斯皮尔曼相关系数计算的python代码
  13. ERP企业管理系统与CRM客户关系管理系统集成套路
  14. Unity不规则按钮
  15. MySQL最全整理!java技术总监面试常见问题及答案
  16. 时间标准 GMT, UTC, CST
  17. MYSQL根据经纬度查询最近距离
  18. 组合数问题(NOIP2016提高组Day2T1)
  19. 演员改行做程序员?一男一女,这两个人你绝对想不到
  20. 如何把canvas元素作为网站背景总结详解

热门文章

  1. struts2中jsp页面上验证码的生成
  2. MYSQL,Oracle,SQL数据库在JSP中的驱动
  3. linux installaccess Nessus-5.2.4
  4. Linux 常用命令:文本查看篇
  5. AM335x 添加 HUAWEI MU609 Mini PCIe Module,并用pppd 启动相关设备
  6. shell 用环境变量的值修改properties文件
  7. dispatchTouchEvent onInterceptTouchEvent onTouchEvent区分
  8. 将一个压缩文件分成多个压缩文件;RAR文件分卷
  9. 超棒的在线Bootstrap主题编辑工具 - lollytin
  10. .netCHARTING图表控件详细介绍及下载