我经常申请工作只是为了测试我的技能。我最近申请了一个,不得不提交一个Java问题,但被拒绝了。请有人简要回顾一下我的申请,告诉我代码中最严重的错误是什么?我有兴趣提高自己,但我很难弄清楚我需要改进什么。
以下是问题所在:
假设您正在开发一个名为IMS的新仓库库存管理系统。IMS将负责实体、单一地点仓库内的库存跟踪工作。IMS将跟踪产品在仓库内的指定物理位置和每个产品的库存级别。IMS将被部署到繁忙的仓库,支持许多采摘者和重新进货者与单个终端和客户一起工作。库存水平的更新将被实时处理,以防止挑选者试图挑选缺货的产品。假设每个产品将存储在仓库中的一个和唯一一个指定位置。库存调整可能是加性的(再库存)或减法(挑选)。无需在位置和级别之外跟踪其他产品信息。问题在Java中,实现了IMS系统的拾取和补充例程。
IMS接口将是实现的第一个组件;所有相关的域对象都必须已经分发给依赖它的其他团队。
以下是重要的部分:
IMS.java (提供给我们,以创建一个库存)
public interface IMS {
PickingResult pickProduct(String productId, int amountToPick);
RestockingResult restockProduct(String productId, int amountToRestock);
}import java.util.Hashtable;
import java.util.Set;
public class Inventory implements IMS {
private Hashtable<String, Product> products = new Hashtable<String, Product>();
private Hashtable<String, Location> locations = new Hashtable<String, Location>();
public void addLocation(Location location) {
locations.put(location.getName(), location);
}
public void addProduct(Product product, Location location, int amount) {
products.put(product.getName(), product);
location.restockProduct(product.getName(), amount);
}
/*
* returns location that has the product when you pass a product ID to it
*/
public Location getLocationByProductID(String productId) throws Exception {
Set<String> keys = locations.keySet();
Location result = null;
for (String key : keys) {
Location current = locations.get(key);
if (current.hasProduct(productId)) {
if (result == null) {
result = current;
} else {
// oh uh, we found the product in two locations, warning the
// user
throw new Exception("product found in two locations");
}
}
}
return result;
}
public void displayInventory() {
Set<String> keys = locations.keySet();
for (String key : keys) {
Location current = locations.get(key);
System.out.println(current.getName());
current.displayInventory();
}
System.out.println("");
}
@Override
public PickingResult pickProduct(String productId, int amountToPick) {
Location loc = null;
Product product = products.get(productId);
// transaction data
boolean transactionSuccess = false;
String transactionMessage = "";
try {
loc = getLocationByProductID(productId);
if (loc == null) {
throw new Exception("Product " + productId + " wasn't found in any location");
}
int amount = loc.getAmountOfProduct(productId);
if (amount < amountToPick) {
throw new Exception("We do not have enough products for this transaction (quantity available: " + amount
+ "), please restock the product " + productId + "!");
}
loc.pickProduct(productId, amountToPick);
transactionSuccess = true;
transactionMessage = "We have successfully picked " + amountToPick + " items of " + productId;
} catch (Exception e) {
transactionMessage = e.getMessage();
}
return new PickingResult(transactionSuccess, transactionMessage, loc, product, amountToPick);
}
@Override
public RestockingResult restockProduct(String productId, int amountToRestock) {
Location loc = null;
Product product = products.get(productId);
// transaction data
boolean transactionSuccess = false;
String transactionMessage = "";
try {
loc = getLocationByProductID(productId);
if (loc == null) {
throw new Exception("Location wasn't found");
}
loc.restockProduct(productId, amountToRestock);
transactionSuccess = true;
transactionMessage = "We have successfully restocked " + amountToRestock + " items of " + productId;
} catch (Exception e) {
transactionMessage = e.getMessage();
}
return new RestockingResult(transactionSuccess, transactionMessage, loc, product, amountToRestock);
}
}import java.util.Hashtable;
import java.util.Set;
public class Location {
private String name;
private Hashtable<String, Integer> amountByProductID = new Hashtable<String, Integer>();
public Location(String name) {
this.name = name;
}
public void restockProduct(String name, Integer amount) {
Integer previousAmount = getAmountOfProduct(name);
amountByProductID.put(name, previousAmount + amount);
}
/*
* returns false if we don't have enough product
*/
public boolean pickProduct(String name, Integer amount) {
Integer previousAmount = getAmountOfProduct(name);
if (previousAmount < amount) {
// not enough items
return false;
}
amountByProductID.put(name, previousAmount - amount);
return true;
}
public boolean hasProduct(String productId) {
return amountByProductID.get(productId) != null;
}
public Integer getAmountOfProduct(String productId) {
Integer amount = amountByProductID.get(productId);
return amount != null ? amount : 0;
}
public String getName() {
return this.name;
}
public void displayInventory() {
Set<String> keys = amountByProductID.keySet();
for (String productId : keys) {
Integer amount = amountByProductID.get(productId);
System.out.println(" " + productId + ": " + amount.toString());
}
}
}(我重命名了几个变量,这样就不会被其他候选人搜索)。
发布于 2015-09-28 02:31:50
对于Hashtable,h.j.k非常礼貌。反对Hashtable的Java2于1998年问世。那是17年前的事了实际代码的第一行以Hashtable开头。如果我是一名招聘经理,我就会立刻停止阅读。它运行得非常快,使用17年前被废弃的类真的很糟糕。
我没有完全阅读您的代码,但我认为您应该避免异常。如果请求没有答案,我只会将其写入返回值,而不是抛出异常。它可能会发生,不可能的请求将在一个库存管理系统,我不希望整个系统停止,因为一个不可能的要求。异常应该保留给真正的异常事件,我不认为错误请求是库存系统中的异常事件。对标准返回值使用异常也会带来性能成本。其他人可能会争辩说,使用例外是在这里进行的正确方式。甚至有可能他们要求您使用异常来符合他们的API。
发布于 2015-09-28 06:27:50
虽然提到了位置,但它并不存在于给定的接口中,因此,我不确定在没有明确定义的需求的情况下是否会使用它。也就是说,即使您完美地实现了位置,客户端程序也无法在给定的接口中设置位置。(可以在PickingResult和RestockingResult中返回一个位置,但是任何这样的位置都是任意的--您最好为每个位置返回“某个地方”或“在仓库中”)。
IMS接口中还有一些提示;它返回PickingResult和RestockingResult这一事实非常清楚地表明,不需要抛出异常。
当选择/重新进货成功时,PickingResult和RestockingResult值应该是什么?当他们失败时?他们什么时候会失败?
PickingResult和RestockingResult应该是具体的叶类,还是作为接口/抽象类更好?(例如,类似Scala的抽象选项,带有一些()和None子类的具体子类。)
其中一个要求是“这个接口的实现和对共享数据的访问必须是线程安全的。”是否有您的代码不是线程安全的地方?(提示:是的,有几个。)
提示:看看https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicInteger.html。
您需要确切地了解如何使用它(特别是重试),它不会解决所有并发问题,但它将解决大多数并发问题。(哪一个问题不能解决,你能做些什么来解决这个问题?)
https://codereview.stackexchange.com/questions/105857
复制相似问题