A seguir estão perguntas comuns de entrevistas de programação para engenheiros de software Java intermediários e seniores. Há 20 perguntas no total.
- Como determinar se um array é um array ordenado?
Resposta: Você pode comparar os tamanhos dos elementos adjacentes por meio de uma travessia. Se os elementos adjacentes estiverem na ordem de tamanho errada, a matriz não será ordenada.
public boolean isSortedArray(int[] nums) {
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i] > nums[i + 1]) {
return false;
}
}
return true;
}
- Como remover elementos duplicados de um array ordenado?
Resposta: Elementos duplicados adjacentes podem ser excluídos por meio de uma travessia.
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;
}
- Como mesclar duas matrizes classificadas?
Resposta: Duas matrizes classificadas podem ser mescladas em uma nova matriz classificada em uma única passagem.
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;
}
- Como reverter um array?
Resposta: Você pode inverter cada elemento do array de uma só vez.
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;
}
}
- Como calcular a média de um array?
Resposta: Adicione todos os elementos do array e divida pelo comprimento do array.
public double averageArray(int[] nums) {
long sum = 0;
for (int num : nums) {
sum += num;
}
return (double) sum / nums.length;
}
- Como calcular a mediana de um array?
Resposta: Depois de classificar o array, encontre o elemento do meio. Se o comprimento da matriz for par, a média dos dois elementos do meio será a mediana.
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];
}
}
- Como calcular a moda de um array?
Resposta: Você pode contar o número de ocorrências de cada elemento por meio de uma travessia. O elemento que ocorre com mais frequência é a moda.
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;
}
- Como calcular a variância de um array?
Resposta: Subtraia todos os elementos do array, eleve-os ao quadrado, depois some-os e, finalmente, divida-os pelo comprimento do array.
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;
}
- Como calcular o desvio padrão de um array?
Resposta: Depois de calcular a variância, calcule a raiz quadrada da variância.
public double standardDeviationArray(int[] nums) {
double variance = varianceArray(nums);
return Math.sqrt(variance);
}
- Como determinar se uma string é uma string palíndromo?
Resposta: Você pode usar duas travessias para comparar se a primeira metade e a segunda metade da string são iguais.
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;
}
- Como remover todos os caracteres duplicados de uma string?
Resposta: Você pode adicionar cada caractere da string a uma nova matriz de caracteres em uma única passagem ou, se o caractere não estiver presente na matriz de caracteres, adicionar o caractere à matriz de caracteres. Por fim, converta a matriz de caracteres em string.
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);
}
- Como mesclar duas strings?
Resposta: Você pode combinar caracteres de duas strings em uma nova string de uma só vez.
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();
}
- Como calcular a distância de edição de duas strings?
Resposta: Você pode usar programação dinâmica para calcular o número mínimo de operações necessárias para converter uma string em outra.
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];
}
- Como implementar um padrão singleton?
Resposta: Você pode usar o estilo preguiçoso e o estilo faminto para implementar o padrão singleton.
Estilo de homem preguiçoso:
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
Estilo chinês faminto:
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}
- Como implementar um padrão de fábrica?
Resposta: Crie uma classe de fábrica e crie objetos correspondentes com base nos parâmetros passados.
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");
}
}
- Como implementar um padrão de observador?
Resposta: Crie uma interface de observador, uma interface de assunto e observadores concretos e classes de assunto. Notifique todos os observadores quando o estado do tópico mudar.
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!");
}
}
}
}
- Como implementar um padrão de estratégia?
Resposta: Crie uma interface de estratégia e uma classe de estratégia específica. Em tempo de execução, estratégias apropriadas são selecionadas para execução com base em diferentes situações.
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");
}
}
}
- Como implementar um padrão de adaptador?
A implementação do padrão do adaptador requer as seguintes etapas:
- Determine a interface alvo: Primeiro, é necessário esclarecer a interface alvo a ser adaptada, ou seja, a interface que o cliente espera utilizar. Esta interface pode ser uma interface existente ou uma interface abstrata.
- Crie uma classe adaptadora: Crie uma classe adaptadora que implementará a interface de destino e conterá uma instância da classe adaptada dentro dela. A classe adaptadora precisa implementar todos os métodos da interface de destino e chamar os métodos correspondentes da classe adaptada nesses métodos.
- Implementar a interface de destino: Implemente todos os métodos da interface de destino na classe do adaptador, que será usada pelo cliente. Ao implementar esses métodos, os parâmetros passados pelo cliente precisam ser passados para os métodos correspondentes da classe adaptada, e os resultados retornados pelos métodos da classe adaptada são retornados ao cliente.
Aqui está um exemplo simples de implementação do padrão adaptador:
// 目标接口
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();
}
}
Neste exemplo, Target
é a interface de destino, Adaptee
a classe que está sendo adaptada Adapter
e a classe do adaptador. A classe adaptadora Adapter
implementa a interface de destino Target
e chama o método da request()
classe adaptada em seu método . O código do cliente usa a classe adaptadora por meio da interface de destino para implementar a chamada para a classe adaptada .Adaptee
specificRequest()
Target
Adapter
Adaptee
- Título: Problema da Torre de Hanói
Descrição do problema: Use Java para implementar uma solução para resolver o problema da Torre de Hanói. A Torre de Hanói é um problema recursivo clássico que requer mover N discos em um poste de um lado para o outro de acordo com certas regras.
Resposta: A seguir está um exemplo de código que implementa o problema da Torre de Hanói em 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);
}
}
}
- Título: Classe de carrinho de compras
Descrição do problema: Projete uma classe de carrinho de compras, incluindo funções como adicionar produtos, excluir produtos, calcular o preço total, etc.
Resposta: A seguir está uma implementação simples da classe de carrinho de compras:
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;
}
}
A classe do carrinho de compras usa um ArrayList para armazenar objetos de produto. Os métodos de adição de produtos, exclusão de produtos e cálculo do preço total percorrem respectivamente o ArrayList para concluir as operações correspondentes.