Amazon Interview Question
SDE1sCountry: United States
Interview Type: Phone Interview
I feel like no one has done this yet. But here is my code:
public class Material {
private String materialName;
private int fireRating;
private int stressRating;
public Material(String materialName, int fireRating, int stressRating) {
this.materialName = materialName;
this.fireRating = fireRating;
this.stressRating = stressRating;
}
public int getStressRating() {
return stressRating;
}
public int getFireRating() {
return fireRating;
}
}
public abstract class Furniture {
private Material furnitureMaterial;
public Furniture(Material furnitureMaterial) {
this.furnitureMaterial = furnitureMaterial;
}
public abstract int fireTest();
public abstract int stressTest();
public Material getMaterial() {
return furnitureMaterial;
}
}
public class Chair extends Furniture {
public Chair(Material furnitureMaterial) {
super(furnitureMaterial);
}
public int stressTest() {
Material furnitureMaterial = super.getMaterial();
int stressRating = furnitureMaterial.getStressRating();
//TODO perform test
return testResults;
}
public int fireTest() {
Material furnitureMaterial = super.getMaterial();
int fireRating = furnitureMaterial.getFireRating();
//TODO perform test
return testResults;
}
public class Table extends Furniture {
public Table(Material furnitureMaterial) {
super(furnitureMaterial)
}
public int stressTest() {
Material furnitureMaterial = super.getMaterial();
int stressRating = furnitureMaterial.getStressRating();
//TODO perform test
return testResults;
}
public int fireTest() {
Material furnitureMaterial = super.getMaterial();
int stressRating = furnitureMaterial.getStressRating();
//TODO perform test
return testResults;
}
}
Now we could go a bit further and make Furniture its own concrete class and just implement based off of a constructor. But I feel like that approach would limit the potential of Chairs and Tables being seperate objects themselves.
Abstract Classes: Chair, table
Concrete Classes: metal chair, wooden chair, metal table, wooden table
Interface: stressTest(), fireTest()
This is just bad design. The next step would be the interviewer will ask you to add another furniture type "Bed" and another material "Glass" . With this design you will have a explosion of classes.
I think that this may address this issue:
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cmath>
#include<cstring>
#include<iostream>
#include<map>
#include<set>
#include<string>
#define INF 2000000000
#define REP(i,n) for(int i = 0; i < (n); i++)
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define FORD(i, a, b) for(int i = (a); i >= (b); i--)
#define PI pair<int, int>
#define vi vector<int>
#define ST first
#define ND second
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;
class Testable {
public:
virtual ~Testable() {}
virtual bool StressTest() const = 0;
virtual bool FireTest() const = 0;
};
class Material : public Testable{
public:
virtual ~Material() {}
virtual bool StressTest() const = 0;
virtual bool FireTest() const = 0;
};
class Wood : public Material {
public:
virtual bool StressTest() const override { return false; }
virtual bool FireTest() const override { return false; }
};
class Metal : public Material {
public:
virtual bool StressTest() const override { return true; }
virtual bool FireTest() const override { return true; }
};
class Furniture : public Testable {
public:
explicit Furniture(shared_ptr<Material> material) : material_(material) {}
virtual ~Furniture() {}
virtual bool StressTest() const override { return material_->StressTest(); }
virtual bool FireTest() const override { return material_->FireTest(); }
protected:
shared_ptr<Material> material_;
};
class Chair : public Furniture {
public:
explicit Chair(shared_ptr<Material> material) : Furniture(material) {}
};
class Table : public Furniture {
public:
explicit Table(shared_ptr<Material> material) : Furniture(material) {}
};
int main(){
shared_ptr<Material> wood(new Wood());
Chair chair(wood);
Table table(wood);
return 0;
}
<?php
trait Wood {
abstract public function whoiam();
public function stress_test() {
$iam = $this->whoiam();
print "Wood $iam stress test\n";
}
public function fire_test() {
$iam = $this->whoiam();
print "Wood $iam fire test\n";
}
}
trait Metal {
abstract public function whoiam();
public function stress_test() {
$iam = $this->whoiam();
print "Metal $iam stress test\n";
}
public function fire_test() {
$iam = $this->whoiam();
print "Metal $iam stress test\n";
}
}
class Chair {
public function whoiam() {
return "chair";
}
}
class Table {
public function whoiam() {
return "table";
}
}
class WoodChair extends Chair {
use Wood;
}
class WoodTable extends Table {
use Wood;
}
class MetalChair extends Chair {
use Metal;
}
class MetalTable extends Table {
use Metal;
}
$thing = new WoodChair;
$thing->stress_test();
$thing->fire_test();
This is a solution using java Generics. The idea is you can create Furniture made of Metal or Wood. So in future new furniture types can be added and new material types can be added while avoiding class explosion
public abstract class Furniture<T extends Material> {
private String furnitureType;
private T material;
public Furniture() {
};
public Furniture(String type, T material) {
this.furnitureType = type;
this.material = material;
}
public void fireTest() {
System.out.println("Fire Test: This is a " + furnitureType
+ " made of " + material.getClass().getSimpleName());
}
public void stressTest() {
System.out.println("Stress Test: This is a " + furnitureType
+ " made of " + material.getClass().getSimpleName());
}
}
public class Table<T extends Material> extends Furniture<T> {
public Table(T material) {
super("Table", material);
}
}
public class Chair<T extends Material> extends Furniture<T> {
public Chair(T material) {
super("Chair", material);
}
}
public abstract class Material {
public static final String type= "UNKNOWN";
}
public class Metal extends Material{
public static final String type= "Metal";
}
public class Wooden extends Material{
public static final String type= "Wood";
}
//finallly furniture test
import java.util.ArrayList;
import java.util.List;
public class FurnitureTest {
public static void main(String[] args) {
Furniture f1 = new Table<Wooden>(new Wooden());
Furniture f2 = new Chair<Wooden>(new Wooden());
Furniture f3 = new Chair<Metal>(new Metal());
Furniture f4 = new Table<Metal>(new Metal());
List<Furniture> furnitures = new ArrayList<>();
furnitures.add(f1);
furnitures.add(f2);
furnitures.add(f3);
furnitures.add(f4);
for (Furniture furniture : furnitures) {
furniture.fireTest();
furniture.stressTest();
}
}
}
I would like to change this a bit.. public interface Furniture {
public interface Furniture {
public boolean stressTest();
public boolean fireTest();
}
public class FurnitureItem implements Furniture {
protected double weight; protected dementions; //those can be height weight width etc public void stressTest();
public boolean fireTest(){//general tests for the furni}
public boolean stressTest(){//general tests for the furni}
}
public class Chair extends FurnitureItem {
//constructors and new variables added as per the requirements with super keyword
//if posssible private
//getters and setter
public String toString()
{
//say print chair public String stressTests(){//general }public void fireTest(){//general fire tests for the chair}
}
public boolean fireTest(){super();//general tests for the chair}
public boolean stressTest(){super();//general tests for the chair}
}
public class Table extends FurnitureItem {
//constructors and new variables added as per the requirements with super keyword
//if posssible private
//getters and setter
public String toString()
{
//say print Table public String stressTests(){//general }public void fireTest(){//general fire tests for the chair}
}
public boolean fireTest(){super();//general tests for the Table}
public boolean stressTest(){super();//general tests for the Table}
}
public class MetalChair extends Chair {
//more private variable with getter and setter public along with the constructors
@Override
public boolean stressTest() {
super();
//specific to metal chairs
}
@Override
public void fireTest() {
super();
//specific to metal chairs
}
public String toString()
{
super();
//say print type as metal public String stressTests(){//general }public void fireTest(){//general fire tests for the chair}
}
}
public class MetalTable extends Table {
//more private variable with getter and setter public along with the constructors
@Override
public boolean stressTest() {
super();
//specific to metal table
}
@Override
public boolean fireTest() {
Value =super();
//specific to metal table
return if everthing is true;
}
public String toString()
{
super();
//say print type as table public String stressTests(){//general }public void fireTest(){//general fire tests for the chair}
}
}
public class WoodenTable extends Table {
//more private variable with getter and setter public along with the constructors
@Override
public boolean stressTest() {
super();
//specific to metal table
}
@Override
public boolean fireTest() {
Value =super();
//specific to metal table
return if everthing is true;
}
public String toString()
{
super();
//say print type as table public String stressTests(){//general }public void fireTest(){//general fire tests for the chair}
}
}
public class WoodenChair extends Chair {
//more private variable with getter and setter public along with the constructors
@Override
public boolean stressTest() {
super();
//specific to metal table
}
@Override
public boolean fireTest() {
Value =super();
//specific to metal table
return if everthing is true;
}
public String toString()
{
super();
//say print type as table public String stressTests(){//general }public void fireTest(){//general fire tests for the chair}
}
}
public class FactoryClass {
public static void main(String[] args){
//array of furnitureItems
for(FurnitureItem f: array)
{
sysout(tests);
}
}
public static Furniture buildFurniture(String model) {
//java 7
FurnitureItem furni= null;
switch (model) {
case MetalChair:
furni= new MetalChair();
break;
case woodenchair:
car = new woodenchair();
break;
case MetalTable:
car = new MetalTable();
break;
case woodenTable:
car = new woodenTable();
break;
default:
// throw some exception
break;
}
return car;
}
}
I like what some people have suggested to avoid class explosion. Based on that, I have come up with this basic structure. Mind you that there can be many more details added. For instance, for chair, if the back rest breaks first on applying pressure or which leg breaks first. Of course, I haven't really written the class that drives the tests either
public interface IMaterial
{
double GetStressThreshold();
double GetHeatThreshold();
}
public abstract class Material : IMaterial
{
protected double stressThreshold;
protected double heatThreshold;
public Material(double stressThreshold, double heatThreshold)
{
this.stressThreshold = stressThreshold;
this.heatThreshold = heatThreshold;
}
public double GetStressThreshold()
{
return stressThreshold;
}
public double GetHeatThreshold()
{
return heatThreshold;
}
}
public class Wood : Material
{
public Wood(double stressThreshold, double heatThreshold)
: base(stressThreshold, heatThreshold)
{ }
}
public class Metal : Material
{
public Metal(double stressThreshold, double heatThreshold)
: base(stressThreshold, heatThreshold)
{ }
}
public interface ITestableFurniture
{
bool Buckled { get; }
bool Burnt { get; }
void ApplyHeat(double temperature);
void ApplyStress(double psi);
}
public abstract class TestableFurniture : ITestableFurniture
{
protected bool buckled;
protected bool burnt;
protected Material material;
public bool Buckled { get { return buckled; } }
public bool Burnt { get { return burnt; } }
public Material Material { get { return material; } }
public TestableFurniture(Material material)
{
this.material = material;
buckled = burnt = false;
}
public virtual void ApplyHeat(double temperature)
{
if (temperature >= material.GetHeatThreshold())
burnt = true;
}
public virtual void ApplyStress(double psi)
{
if (psi >= material.GetStressThreshold())
buckled = true;
}
}
public class Chair : TestableFurniture
{
public Chair(Material material)
: base(material)
{ }
}
public class Table : TestableFurniture
{
public Table(Material material)
: base(material)
{ }
}
Does the below design sounds reasonable?
- samotgun November 18, 2013