首页新闻找找看学习计划

求助笔试题 -- 找出下面代码中的问题并提出改进方案

0
悬赏园豆:5 [已解决问题] 解决于 2019-10-19 18:19

小弟最近面试遇到一个题目,一个关于客户旅行行程的类,有一些操作,包括一些异步操作。
要求找出其中写的不好的地方,并提出改进方案

根据好的编码标准和设计,检查以下代码,这是部分实现的一个行程计划。指出您可以在代码中看到的任何问题(如果有的话),以及应该做些什么来改进它们。

/// <summary>
/// Provides capabilities for managing a customers itinerary.
/// </summary>
public class ItineraryManager
{
private readonly IDataStore _dataStore;
private readonly IDistanceCalculator _distanceCalculator;

public ItineraryManager()
{
    _dataStore = new SqlAgentStore(ConfigurationManager.ConnectionStrings["SqlDbConnection"].ConnectionString);
    _distanceCalculator = new GoogleMapsDistanceCalculator(ConfigurationManager.AppSettings["GoogleMapsApiKey"]);
}

/// <summary>
/// Calculates a quote for a customers itinerary from a provided list of airline providers.
/// </summary>
/// <param name="itineraryId">The identifier of the itinerary</param>
/// <param name="priceProviders">A collection of airline price providers.</param>
/// <returns>A collection of quotes from the different airlines.</returns>
public IEnumerable<Quote> CalculateAirlinePrices(int itineraryId, IEnumerable<IAirlinePriceProvider> priceProviders)
{
    var itinerary = _dataStore.GetItinaryAsync(itineraryId).Result;
    if (itinerary == null)
        throw new InvalidOperationException();

    List<Quote> results = new List<Quote>();
    Parallel.ForEach(priceProviders, provider =>
    {
        var quotes = provider.GetQuotes(itinerary.TicketClass, itinerary.Waypoints);
        foreach (var quote in quotes)
            results.Add(quote);
    });
    return results;
}

/// <summary>
/// Calculates the total distance traveled across all waypoints in a customers itinerary.
/// </summary>
/// <param name="itineraryId">The identifier of the itinerary</param>
/// <returns>The total distance traveled.</returns>
public async Task<double> CalculateTotalTravelDistanceAsync(int itineraryId)
{
    var itinerary = await _dataStore.GetItinaryAsync(itineraryId);
    if (itinerary == null)
        throw new InvalidOperationException();
    double result = 0;
    for(int i=0; i<itinerary.Waypoints.Count-1; i++)
    {
        result = result + _distanceCalculator.GetDistanceAsync(itinerary.Waypoints[i],
             itinerary.Waypoints[i + 1]).Result;
    }
    return result;
}

/// <summary>
/// Loads a Travel agents details from Storage
/// </summary>
/// <param name="id">The id of the travel agent.</param>
/// <param name="updatedPhoneNumber">If set updates the agents phone number.</param>
/// <returns>The travel agent if located, otherwise null.</returns>
public TravelAgent FindAgent(int id, string updatedPhoneNumber)
{
    var agentDao = _dataStore.GetAgent(id);
    if (agentDao == null)
        return null;
    if (!string.IsNullOrWhiteSpace(updatedPhoneNumber))
    {
        agentDao.PhoneNumber = updatedPhoneNumber;
        _dataStore.UpdateAgent(id, agentDao);
    }
    return Mapper.Map<TravelAgent>(agentDao);
}

}

新西兰程序员的主页 新西兰程序员 | 初学一级 | 园豆:1
提问于:2019-10-13 16:39
< >
分享
最佳答案
0

List<Quote> results = new List<Quote>();
Parallel.ForEach(priceProviders, provider =>
{
var quotes = provider.GetQuotes(itinerary.TicketClass, itinerary.Waypoints);
foreach (var quote in quotes)
results.Add(quote);
});
return results;
Parallel.ForEach我记得没错会执行多线程,但是直线的线程都共用同一个实例results ,这样可能会导致results 有重复数据

收获园豆:5
灬丶 | 初学一级 |园豆:85 | 2019-10-15 13:50
其他回答(2)
-1

你好,在线等大神解答

Yvonne718 | 园豆:254 (菜鸟二级) | 2019-10-14 09:43
0

先说一个呗
并行计算下的线程安全

孤月星霜 | 园豆:256 (菜鸟二级) | 2019-10-14 14:58

什么意思
这个代码有问题么

有线程安全的问题么
Parallel.ForEach(priceProviders, provider =>
{
var quotes = provider.GetQuotes(itinerary.TicketClass, itinerary.Waypoints);
foreach (var quote in quotes)
results.Add(quote);
});

支持(0) 反对(0) 新西兰程序员 | 园豆:1 (初学一级) | 2019-10-14 15:25

@新西兰程序员: 最后results里的数据可能会比正常的少。比如在resuls内对象数量为5时被两个线程同时获取到然后插入一条记录,最终得到的就会是数量为6 而不是7

支持(0) 反对(0) 孤月星霜 | 园豆:256 (菜鸟二级) | 2019-10-17 13:25

@孤月星霜:
那是不是说,我就用C#中普通的foreach循环就可以,在这里
而不要用Parallel.ForEach
对么

支持(0) 反对(0) 新西兰程序员 | 园豆:1 (初学一级) | 2019-10-17 13:35

@新西兰程序员: 循环是一种;还有一种是用 ParallelQuery 替换 Parallel
比如:priceProviders.AsParallel()
具体用哪一种看你循环是否耗时了

支持(0) 反对(0) 孤月星霜 | 园豆:256 (菜鸟二级) | 2019-10-17 13:54

@孤月星霜:
不知道啊,这就是一道笔试题,所有代码都在这里
我按照你的建议,改成了foreach 提交上去了

支持(0) 反对(0) 新西兰程序员 | 园豆:1 (初学一级) | 2019-10-17 13:55

@新西兰程序员: 这还可以隔好几天之后再提交的呀....

支持(0) 反对(0) 孤月星霜 | 园豆:256 (菜鸟二级) | 2019-10-17 14:02

@新西兰程序员: 那这个代码还有好几处需要修改的 哈哈 你仔细找找

支持(0) 反对(0) 孤月星霜 | 园豆:256 (菜鸟二级) | 2019-10-17 14:05

@孤月星霜:
能够帮我指出来一下么
我也找了一些
就怕漏掉了

支持(0) 反对(0) 新西兰程序员 | 园豆:1 (初学一级) | 2019-10-17 14:21
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册