以下は、中級および上級 Java ソフトウェア エンジニア向けのプログラミング面接でよくある質問で、合計 20 問あります。
- 配列が順序付けされた配列かどうかを判断するにはどうすればよいですか?
回答: 1 回の走査で、隣接する要素のサイズを比較できます。隣接する要素のサイズ順序が間違っていることが判明した場合、配列は順序付けされません。
public boolean isSortedArray(int[] nums) {
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i] > nums[i + 1]) {
return false;
}
}
return true;
}
- 順序付けられた配列から重複した要素を削除するにはどうすればよいですか?
回答: 隣接する重複要素は 1 回の走査で削除できます。
public int[] removeDuplicates(int[] nums) {
if (nums == null || nums.length == 0) {
return null;
}
int i = 0;
for (int j = 0; j < nums.length; j++) {
if (i == 0 || nums[j]!= nums[i]) {
nums[i++] = nums[j];
}
}
int[] result = new int[i];
System.arraycopy(nums, 0, result, 0, i);
return result;
}
- 2 つのソートされた配列をマージするにはどうすればよいですか?
回答: 2 つのソートされた配列を 1 回のパスで新しいソートされた配列にマージできます。
public int[] mergeTwoSortedArrays(int[] nums1, int[] nums2) {
int[] result = new int[nums1.length + nums2.length];
int i = 0, j = 0, k = 0;
while (i < nums1.length && j < nums2.length) {
if (nums1[i] < nums2[j]) {
result[k++] = nums1[i++];
} else {
result[k++] = nums2[j++];
}
}
while (i < nums1.length) {
result[k++] = nums1[i++];
}
while (j < nums2.length) {
result[k++] = nums2[j++];
}
return result;
}
- 配列を反転するにはどうすればよいですか?
回答: 1 回のパスで配列の各要素を反転できます。
public void reverseArray(int[] nums) {
for (int i = 0; i < nums.length; i++) {
int temp = nums[i];
nums[i] = nums[nums.length - 1 - i];
nums[nums.length - 1 - i] = temp;
}
}
- 配列の平均を計算するにはどうすればよいですか?
答え: 配列のすべての要素を加算し、配列の長さで割ります。
public double averageArray(int[] nums) {
long sum = 0;
for (int num : nums) {
sum += num;
}
return (double) sum / nums.length;
}
- 配列の中央値を計算するにはどうすればよいですか?
回答: 配列をソートした後、中央の要素を見つけます。配列の長さが偶数の場合、中央の 2 つの要素の平均が中央値になります。
public double medianArray(int[] nums) {
Arrays.sort(nums);
int length = nums.length;
if (length % 2 == 0) {
return (double) (nums[length / 2 - 1] + nums[length / 2]) / 2.0;
} else {
return (double) nums[length / 2];
}
}
- 配列のモードを計算するにはどうすればよいですか?
回答: 1 回の走査で各要素の出現数をカウントできます。最も頻繁に発生する要素はモードです。
public int mostCommon(int[] nums) {
int[] count = new int[101];
for (int num : nums) {
count[num]++;
}
int max = 0;
int res
for (int i = 0; i < 101; i++) {
if (count[i] > max) {
max = count[i];
res = i;
}
}
return res;
}
- 配列の分散を計算するにはどうすればよいですか?
答え: 配列のすべての要素を減算し、2 乗してから合計し、最後に配列の長さで割ります。
public double varianceArray(int[] nums) {
long sum = 0;
for (int num : nums) {
sum += num;
}
double mean = (double) sum / nums.length;
double sumSqr = 0;
for (int num : nums) {
double d = num - mean;
sumSqr += d * d;
}
return sumSqr / nums.length;
}
- 配列の標準偏差を計算するにはどうすればよいですか?
回答: 分散を計算した後、分散の平方根を求めます。
public double standardDeviationArray(int[] nums) {
double variance = varianceArray(nums);
return Math.sqrt(variance);
}
- 文字列が回文文字列であるかどうかを判断するにはどうすればよいですか?
回答: 2 つの走査を使用して、文字列の前半と後半が同じかどうかを比較できます。
public boolean isPalindrome(String s) {
int i = 0;
int j = s.length() - 1;
while (i < j) {
if (s.charAt(i)!= s.charAt(j)) {
return false;
}
i++;
j--;
}
return true;
}
- 文字列からすべての重複文字を削除するにはどうすればよいですか?
回答: 文字列内の各文字を 1 回のパスで新しい文字配列に追加できます。または、文字が文字配列に存在しない場合は、その文字を文字配列に追加できます。最後に文字配列を文字列に変換します。
public String removeDuplicates(String s) {
if (s == null || s.length() == 0) {
return null;
}
char[] chars = new char[s.length()];
for (int i = 0; i < s.length(); i++) {
if (chars[i]!= s.charAt(i)) {
chars[chars.length - 1] = s.charAt(i);
}
}
return new String(chars);
}
- 2 つの文字列をマージするにはどうすればよいですか?
回答: 1 回のパスで 2 つの文字列の文字を新しい文字列に結合できます。
public String mergeStrings(String s1, String s2) {
if (s1 == null) {
return s2;
}
if (s2 == null) {
return s1;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < Math.max(s1.length(), s2.length()); i++) {
char c1 = (i < s1.length())? s1.charAt(i) : '\0';
char c2 = (i < s2.length())? s2.charAt(i) : '\0';
sb.append(c1);
sb.append(c2);
}
return sb.toString();
}
- 2 つの文字列の編集距離を計算するにはどうすればよいですか?
回答: 動的プログラミングを使用すると、ある文字列を別の文字列に変換するために必要な最小操作数を計算できます。
public int editDistance(String s1, String s2) {
int m = s1.length();
int n = s2.length();
int[][] dp = new int[m + 1][n + 1];
for (int i = 0; i <= m; i++) {
for (int j = 0; j <= n; j++) {
if (i == 0) {
dp[i][j] = j;
} else if (j == 0) {
dp[i][j] = i;
} else if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1;
}
}
}
return dp[m][n];
}
- シングルトンパターンを実装するにはどうすればよいですか?
回答: 遅延スタイルとハングリー スタイルを使用してシングルトン パターンを実装できます。
怠け者のスタイル:
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
お腹を空かせた中華風:
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}
- ファクトリ パターンを実装するにはどうすればよいですか?
回答: ファクトリ クラスを作成し、渡されたパラメーターに基づいて対応するオブジェクトを作成します。
public class Factory {
public static void main(String[] args) {
Product productA = factory.createProductA();
Product productB = factory.createProductB();
productA.display();
productB.display();
}
public static Product createProductA() {
return new ProductA();
}
public static Product createProductB() {
return new ProductB();
}
}
abstract class Product {
public abstract void display();
}
class ProductA extends Product {
public void display() {
System.out.println("Product A");
}
}
class ProductB extends Product {
public void display() {
System.out.println("Product B");
}
}
- オブザーバー パターンを実装するにはどうすればよいですか?
回答: オブザーバー インターフェイス、サブジェクト インターフェイス、具体的なオブザーバー クラスとサブジェクト クラスを作成します。トピックの状態が変化したときにすべてのオブザーバーに通知します。
public class ObserverPattern {
public static void main(String[] args) {
Subject subject = new Subject();
Observer observer1 = new ConcreteObserver(subject);
Observer observer2 = new ConcreteObserver(subject);
subject.addObserver(observer1);
subject.addObserver(observer2);
subject.notifyObservers();
}
public static interface Subject {
void addObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
public static interface Observer {
void update(String message);
}
public static class ConcreteObserver implements Observer {
private Subject subject;
public ConcreteObserver(Subject subject) {
this.subject = subject;
}
@Override
public void update(String message) {
System.out.println("Received: " + message);
}
}
public static class ConcreteSubject implements Subject {
private List<Observer> observers;
public ConcreteSubject() {
observers = new ArrayList<>();
}
@Override
public void addObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update("Hello, World!");
}
}
}
}
- 戦略パターンを実装するにはどうすればよいですか?
回答: 戦略インターフェイスと特定の戦略クラスを作成します。実行時には、さまざまな状況に基づいて、実行する適切な戦略が選択されます。
public class StrategyPattern {
public static void main(String[] args) {
Strategy strategy = new DefaultStrategy();
strategy.execute();
strategy = new CustomStrategy();
strategy.execute();
}
public static interface Strategy {
void execute();
}
public static class DefaultStrategy implements Strategy {
@Override
public void execute() {
System.out.println("Default strategy");
}
}
public static class CustomStrategy implements Strategy {
@Override
public void execute() {
System.out.println("Custom strategy");
}
}
}
- アダプター パターンを実装するにはどうすればよいですか?
アダプター パターンを実装するには、次の手順が必要です。
- ターゲット インターフェイスを決定する: まず、適応するターゲット インターフェイス、つまりクライアントが使用すると予想されるインターフェイスを明確にする必要があります。このインターフェイスは、既存のインターフェイスまたは抽象インターフェイスにすることができます。
- アダプター クラスを作成する: ターゲット インターフェイスを実装し、その中に適応されたクラスのインスタンスを含むアダプター クラスを作成します。アダプター クラスは、ターゲット インターフェイスのすべてのメソッドを実装し、これらのメソッド内で適応されたクラスの対応するメソッドを呼び出す必要があります。
- ターゲット インターフェイスの実装: クライアントによって使用されるターゲット インターフェイスのすべてのメソッドをアダプター クラスに実装します。これらのメソッドを実装する場合、クライアントから渡されたパラメータを適応クラスの対応するメソッドに渡し、適応クラスのメソッドによって返された結果をクライアントに返す必要があります。
アダプター パターンの簡単な実装例を次に示します。
// 目标接口
public interface Target {
void request();
}
// 被适配的类
public class Adaptee {
public void specificRequest() {
System.out.println("被适配的类的方法被调用");
}
}
// 适配器类
public class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void request() {
adaptee.specificRequest();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Adaptee adaptee = new Adaptee();
Target target = new Adapter(adaptee);
target.request();
}
}
この例では、ターゲット インターフェイス、適応されるクラス、およびアダプター クラスTarget
です。アダプター クラスはターゲット インターフェイスを実装し、そのメソッド内で適応されたクラスのメソッドを呼び出します。クライアント コードは、ターゲット インターフェイスを介してアダプター クラスを使用して、適応されたクラスへの呼び出しを実装します。Adaptee
Adapter
Adapter
Target
request()
Adaptee
specificRequest()
Target
Adapter
Adaptee
- タイトル: ハノイの塔問題
問題の説明: Java を使用して、ハノイの塔問題を解決するソリューションを実装してください。ハノイの塔は古典的な再帰問題であり、特定のルールに従ってポール上の N 個のディスクを一方の側からもう一方の側に移動する必要があります。
回答: 以下は、Java でハノイの塔の問題を実装するサンプル コードです。
public class HanoiTower {
public static void main(String[] args) {
int n = 3; // 设置盘子的数量
hanoi(n, 'A', 'B', 'C');
}
/**
* 汉诺塔递归方法
* @param n 盘子数量
* @param from 源柱子
* @param auxiliary 辅助柱子
* @param to 目标柱子
*/
public static void hanoi(int n, char from, char auxiliary, char to) {
if (n == 1) {
// 当只有一个盘子时,直接从源柱子移动到目标柱子
System.out.println("Move disk 1 from " + from + " to " + to);
} else {
// 将 n-1 个盘子从源柱子借助目标柱子移动到辅助柱子
hanoi(n - 1, from, to, auxiliary);
// 将第 n 个盘子从源柱子移动到目标柱子
System.out.println("Move disk " + n + " from " + from + " to " + to);
// 将 n-1 个盘子从辅助柱子借助源柱子移动到目标柱子
hanoi(n - 1, auxiliary, from, to);
}
}
}
- タイトル: ショッピング カート クラス
問題の説明: 商品の追加、商品の削除、合計金額の計算などの機能を含むショッピング カート クラスを設計してください。
回答: 以下は、単純なショッピング カート クラスの実装です。
public class ShoppingCart {
private ArrayList<Item> items;
public ShoppingCart() {
items = new ArrayList<>();
}
/**
* 向购物车添加商品
* @param item 商品对象
*/
public void addItem(Item item) {
for (int i = 0; i < items.size(); i++) {
if (items.get(i) == item) {
items.set(i, item);
return;
}
}
items.add(item);
}
/**
* 从购物车中删除商品
* @param item 商品对象
* @return 是否成功删除
*/
public boolean removeItem(Item item) {
for (int i = 0; i < items.size(); i++) {
if (items.get(i) == item) {
items.remove(i);
return true;
}
}
return false;
}
/**
* 计算购物车中商品的总价
* @return 总价
*/
public double calculateTotal() {
double total = 0;
for (Item item : items) {
total += item.getPrice();
}
return total;
}
}
ショッピング カート クラスは、ArrayList を使用して製品オブジェクトを格納します。製品の追加、製品の削除、および合計価格の計算のメソッドは、それぞれ ArrayList を横断して、対応する操作を完了します。