.NET面试,代码结构和设计

时间:2012-06-22 03:12:26

标签: c# code-structure

我在接受采访时得到了以下.NET问题。我不知道为什么我得分低。不幸的是我没有得到反馈。

问题:

文件hockey.csv包含来自Hockey Premier League的结果。 “For”和“Against”栏目包含了那个赛季每支球队得分的目标总数(因此阿拉巴马队在对阵对手的比赛中打入79球,并且有36个进球)。

编写一个程序来打印团队名称,其中“for”和“against”目标的差异最小。

hockey.csv的结构看起来像这样(它是一个有效的csv文件,但我只是复制了这里的值以获得一个想法)

团队 - For - Against

Alabama 79 36

Washinton 67 30

Indiana 87 45

纽卡斯尔74 52

佛罗里达州53 37

纽约46 47

桑德兰29 51

Lova 41 64

内华达州33 63

Boston 30 64

内华达州33 63

Boston 30 64

解决方案:

class Program
{
    static void Main(string[] args)
    {
        string path = @"C:\Users\<valid csv path>";

        var resultEvaluator = new ResultEvaluator(string.Format(@"{0}\{1}",path, "hockey.csv"));
        var team = resultEvaluator.GetTeamSmallestDifferenceForAgainst();

        Console.WriteLine(
            string.Format("Smallest difference in ‘For’ and ‘Against’ goals > TEAM: {0}, GOALS DIF: {1}",
            team.Name, team.Difference ));

        Console.ReadLine();
    }
}

public interface IResultEvaluator
{
    Team GetTeamSmallestDifferenceForAgainst();
}

public class ResultEvaluator : IResultEvaluator
{
    private static DataTable leagueDataTable;
    private readonly string filePath;
    private readonly ICsvExtractor csvExtractor;

    public ResultEvaluator(string filePath){
        this.filePath = filePath;
        csvExtractor = new CsvExtractor();
    }

    private DataTable LeagueDataTable{
        get
        {
            if (leagueDataTable == null)
            {
                leagueDataTable = csvExtractor.GetDataTable(filePath);
            }

            return leagueDataTable;
        }
    }

    public Team GetTeamSmallestDifferenceForAgainst() {
        var teams = GetTeams();
        var lowestTeam = teams.OrderBy(p => p.Difference).First();
        return lowestTeam;
    }

    private IEnumerable<Team> GetTeams() {
        IList<Team> list = new List<Team>();

        foreach (DataRow row in LeagueDataTable.Rows)
        {
            var name = row["Team"].ToString();
            var @for = int.Parse(row["For"].ToString());
            var against = int.Parse(row["Against"].ToString());
            var team = new Team(name, against, @for);
            list.Add(team);
        }

        return list;
    }
}

public interface ICsvExtractor
{
    DataTable GetDataTable(string csvFilePath);
}

public class CsvExtractor : ICsvExtractor
{
    public DataTable GetDataTable(string csvFilePath)
    {
        var lines = File.ReadAllLines(csvFilePath);

        string[] fields;

        fields = lines[0].Split(new[] { ',' });
        int columns = fields.GetLength(0);
        var dt = new DataTable();

        //always assume 1st row is the column name.
        for (int i = 0; i < columns; i++)
        {
            dt.Columns.Add(fields[i].ToLower(), typeof(string));
        }

        DataRow row;
        for (int i = 1; i < lines.GetLength(0); i++)
        {
            fields = lines[i].Split(new char[] { ',' });

            row = dt.NewRow();
            for (int f = 0; f < columns; f++)
                row[f] = fields[f];
            dt.Rows.Add(row);
        }

        return dt;
    }
}

public class Team
{
    public Team(string name, int against, int @for)
    {
        Name = name;
        Against = against;
        For = @for;
    }

    public string Name { get; private set; }

    public int Against { get; private set; }

    public int For { get; private set; }

    public int Difference
    {
        get { return (For - Against); }
    }
}

输出: for' and与'目标&gt;的最小差异团队:波士顿,目标DIF:-34

有人可以查看我的代码并在此处看到任何明显错误的内容吗?他们只关心代码的结构/设计以及程序是否产生正确的结果(即最小差异)。非常感谢。

3 个答案:

答案 0 :(得分:11)

也许是因为你写了这么多行代码,当它可以只是

var teamRecords = File.ReadAllLines("path");
var currentLow = int.MaxValue;
foreach (var record in teamRecords.Skip(1).ToList())
{
    var tokens = record.Split(',');
    if (tokens.Length == 3)
    {
        int forValue = 0;
        int againstValue = 0;

        if (int.TryParse(tokens[1], out forValue) && int.TryParse(tokens[2], out againstValue))
        {
            var difference = Math.Abs(forValue - againstValue);
            if (difference < currentLow) currentLow = difference;
        }
     }
 }

 Console.WriteLine(currentLow);

答案 1 :(得分:6)

我想你错过了解这个问题。面试官询问“目标”和“反对”目标之间的最小差异,而您的计划正在计算最佳目标平均值。如果您看到最小差异,那么纽约不是波士顿。让我在这里更新 fenix2222 代码。

var teamRecords = File.ReadAllLines(Path.Combine(Application.StartupPath,"teams.csv"));
            var currentLow = int.MaxValue; //just to make sure that difference is initially less than currentLow.
            foreach (var record in teamRecords.Skip(1).ToList())
            {
                var tokens = record.Split(',');
                if (tokens.Length == 3)
                {
                    int forValue = 0;
                    int againstValue = 0;

                    if (int.TryParse(tokens[1], out forValue) && int.TryParse(tokens[2], out againstValue))
                    {
                        var difference = 0;
                        if (forValue > againstValue)
                            difference = forValue - againstValue;
                        else
                            difference = againstValue - forValue;

                        if (difference < currentLow) 
                            currentLow = difference;
                    }
                }
            }

答案 2 :(得分:3)

粗略概述中的一些内容:

  1. 有两个接口,但它们的任何一个用途都没有价值。
  2. 将问题陈述引入DataTable是没有理由的。
  3. 代码过于复杂。
  4. 在GetTeams方法中使用IList和IEnumerable看起来是'仅仅因为'。
  5. ResultEvaluator类不可重用,即,只要实例化该类,就永远不能重新设置csv文件。你只能一遍又一遍地调用相同的方法(GetTeamSmallestDifferenceForAgainst);没有其他公共财产可供使用。
  6. 在GetDataTable方法中,字符串[]字段在一行上声明,然后在下一行设置该值。
  7. 在Team类的构造函数中使用@符号作为'for'参数的原因不足0;只需将保留字'for'重命名为其他内容。
  8. 3.5+ .NET中有许多构造可以更容易地解决问题;这只是表明对语言缺乏了解。
  9. 从外观上看,你似乎试图表明你比问题陈述中提出的要多得多。但是,你知道如何在这个练习中使用的知识是非常可怕的,而且不是很好。

    将来,我建议只是解决手头的问题,不要过度思考。保持简单。