În vederea pregătirii interviului tehnic, necesar pentru admiterea în cadrul cursului Java Software Development - Modul Junior Developer îți recomandăm să rezolvi următoarele exerciții.
Chiar dacă ai mai lucrat anterior în Java, rezolvarea exercițiilor va contribui la reîmprospătarea unor cunoștințe esențiale la interviu și parcurse în cadrul Modulului pentru Începători, precum:
Sintaxa limbajului Java.
Fluxul unui program, algoritmi de bază în programare.
Concepte primitive de programare orientată obiect (i.e. OOP).
Pentru fiecare exercițiu am atașat câte un model de rezolvare. Acesta nu este unic, ci reprezintă doar o soluție validă, elegantă și optimă pe care o poți folosi pentru verificarea codului scris de tine. Îți recomandăm să petreci cel puțin 30 minute - 1 oră pentru fiecare cerință și să încerci să rezolvi inițial singur exercițiile, înainte să citești soluția oficială.
1. Scrie o metodă care primește ca parametru un număr natural x
și apoi afișează:
cifrele numărului (în ordine inversă).
suma cifrelor.
// n == 21_304
Cifrele numarului sunt: 4, 0, 3, 1, 2,
Suma cifrelor este: 10
Soluție
public static void displayDigitsAndSum(int x) {
int sum = 0;
System.out.print("Cifrele numarului sunt: ");
while (x > 0) {
int lastDigit = x % 10;
System.out.print(lastDigit + ", ");
sum += lastDigit;
x /= 10;
}
System.out.println();
System.out.println("Suma cifrelor este: " + sum);
}
2. Se citește un număr natural n
și apoi n
numere întregi. Scrie un program care calculează și afișează:
cel mai mic număr (valoarea minimă din șir).
cel mai mare număr (valoarea maximă din șir).
media aritmetică a numerelor (calculată ca sumă a tuturor numerelor împărțită la numărul de numere).
// n == 7
// numerele citite: 1 15 0 21 14 101 1
Numarul minim: 0
Numarul maxim: 101
Media aritmetica: 21.857142857
Soluție
- Ex2.java
package ro.devmind;
import java.util.Scanner;
public class Ex2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int crtNumber = sc.nextInt();
int minValue = crtNumber;
int maxValue = crtNumber;
double mean = crtNumber;
for (int i = 1; i < n; i++) {
crtNumber = sc.nextInt();
mean += crtNumber;
if (minValue > crtNumber) {
minValue = crtNumber;
}
if (maxValue < crtNumber) {
maxValue = crtNumber;
}
}
mean /= n;
System.out.println("Numarul minim: " + minValue);
System.out.println("Numarul maxim: " + maxValue);
System.out.println("Media aritmetica: " + mean);
}
}
3. Scrie o metodă care să determine dacă un număr dat este număr prim. Metoda va returna true
dacă numărul este număr prim și false
în caz contrar.
Idee de rezolvare
Pentru a determina dacă un număr este prim, este necesar să testăm dacă există vreun divizor în afară de 1
și el însuși. În cazul în care găsim cel puțin un divizor, numărul nu este prim.
Soluție
public static boolean isPrime(int number) {
if (number < 2) {
return false;
}
for (int i = 2; i <= number / 2; i++) {
if (number % i == 0) {
return false;
}
}
return true;
}
3.1. Scrie un algoritm care citește de la tastatură un număr n
și afișează toate numerele prime până la n
(inclusiv), începând cu 2
.
Tips
Folosește în rezolvare metoda definită la Exercițiul 3.
// INPUT -> OUTPUT
10 -> 2, 3, 5, 7,
20 -> 2, 3, 5, 7, 11, 13, 17, 19,
97 -> 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,
Soluție
- Ex31.java
package ro.devmind;
import java.util.Scanner;
public class Ex31 {
public static boolean isPrime(int number) {
if (number < 2) {
return false;
}
for (int i = 2; i <= number / 2; i++) {
if (number % i == 0) {
return false;
}
}
return true;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
for (int i = 2; i <= n; i++) {
if (isPrime(i)) {
System.out.print(i + " ");
}
}
System.out.println();
}
}
3.2. Implementează un program care afișează toți divizorii proprii (adică toți divizorii fără 1
și numărul însuși) ai unui număr natural n
citit de la tastatură. În cazul în care numărul este prim (i.e. nu are divizori proprii), programul va afișa mesajul Este numar prim
. Câteva exemple sunt:
// INPUT -> OUTPUT
12 -> 2 3 4 6
15 -> 3 5
24 -> 2 3 4 6 8 12
13 -> Este numar prim
Soluție
- Ex32.java
package ro.devmind;
import java.util.Scanner;
public class Ex32 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int number = sc.nextInt();
boolean hasDivisors = false;
for (int i = 2; i <= number / 2; i++) {
if (number % i == 0) {
hasDivisors = true;
System.out.print(i + " ");
}
}
if (hasDivisors == false) {
System.out.print("Este numar prim");
}
System.out.println();
}
}
1. Implementează o metodă (i.e. countOccurrencesIgnoreCase(String[] array, String key)
) care determină numărul de elemente key
din cadrul array
și returnează această valoare. Metoda nu ține cont de tipul literelor (i.e. majuscule vs. minuscule). Testează metoda în main
pentru cât mai multe cazuri de excepție.
// Exemplul 1:
ARGUMENTS: ["Java", "C", "Python", "JAVA", "perl", "C#", "java"], "JAVA"
RETURN: 3
// Exemplul 2:
ARGUMENTS: ["Java", "C", "Python", "JAVA", "perl", "C#", "java"], "TensorFlow"
RETURN: 0
Soluție
- Ex1.java
package ro.devmind;
import java.util.Scanner;
public class Ex1 {
public static int countOccurrencesIgnoreCase(String[] array, String key) {
int counter = 0;
for (int i = 0; i < array.length; i++) {
if (array[i].equalsIgnoreCase(key)) {
counter++;
}
}
return counter;
}
public static void main(String[] args) {
// Test 1
String[] array1 = {};
String key1 = "aKey";
System.out.println("Test 1: " + countOccurrencesIgnoreCase(array1, key1));
// Test 2
String[] array2 = {"Java", "C", "Python", "JAVA", "perl", "C#", "java"};
String key2 = "JAVA";
System.out.println("Test 2: " + countOccurrencesIgnoreCase(array2, key2));
// Test 3
String key3 = "JA VA";
System.out.println("Test 3: " + countOccurrencesIgnoreCase(array2, key3));
// Test 4
String key4 = "TensorFlow";
System.out.println("Test 4: " + countOccurrencesIgnoreCase(array2, key4));
}
}
2. Un număr palindrom este un număr care este egal cu simetricul său (ex: 121, 10001, 22344322, 88, 7 etc.). Similar, un șir de caractere este palindrom dacă este identic cu simetricul său (ex: „abba“, „ana“, „noon“, „radar“, „madam“). Implementează o metodă (i.e. isPalindromeIgnoreCase(String)
) care determină dacă un șir de caractere primit ca parametru este sau nu palindrom, fără a se ține cont de tipul literelor (i.e. majuscule vs. minuscule). Testează metoda în main
pentru cât mai multe cazuri de excepție.
// Exemplul 1:
ARGUMENTS: "dog"
RETURN: false
// Exemplul 2:
ARGUMENTS: "Madam"
RETURN: true
Soluție
- Ex2.java
package ro.devmind;
import java.util.Scanner;
public class Test {
public static boolean isPalindromeIgnoreCase(String word) {
String lowerCaseWord = word.toLowerCase();
// reverse the string using the StringBuilder class
StringBuilder sb = new StringBuilder(lowerCaseWord);
String reverseLowerCaseWord = sb.reverse().toString();
if (lowerCaseWord.equals(reverseLowerCaseWord)) {
return true;
}
return false;
}
public static void main(String[] args) {
// Test 1
System.out.println("Test 1: " + isPalindromeIgnoreCase(""));
// Test 2
System.out.println("Test 2: " + isPalindromeIgnoreCase("dog"));
// Test 3
System.out.println("Test 3: " + isPalindromeIgnoreCase("MadAM"));
// Test 4
System.out.println("Test 4: " + isPalindromeIgnoreCase("Rotator"));
}
}
3. Pornind de la experiența acumulată la exercițiul anterior, implementează o metodă (i.e. isPalindromeIgnoreCasePRO(String)
) care determină dacă o propoziție este palindrom, ignorând diferențele de litere mari / mici și toate caracterele care nu sunt litere. Similar exercițiului precedent, metoda va returna true
dacă șirul de caractere este palindrom, sau false
în caz contrar.
// Exemplul 1:
ARGUMENTS: "Red rum, sir, is murder!"
RETURN: true
// Exemplul 2:
ARGUMENTS: "Was it a cat I saw?"
RETURN: true
// Exemplul 3:
ARGUMENTS: "Not a palindrom, I'm afraid.."
RETURN: false
// Exemplul 4:
ARGUMENTS: "Step on no pets."
RETURN: true
Soluție
- Ex3.java
package ro.devmind;
import java.util.Scanner;
public class Ex3 {
public static boolean isPalindromeIgnoreCasePRO(String sentence) {
String lowerCaseSentence = sentence.toLowerCase();
// filter sentence for non-letters characters using the StringBuilder class
StringBuilder sb = new StringBuilder();
for (int i = 0; i < lowerCaseSentence.length(); i++) {
if (Character.isLetter(lowerCaseSentence.charAt(i))) {
sb.append(lowerCaseSentence.charAt(i));
}
}
String onlyLettersSentence = sb.toString();
String onlyLettersSentenceReverse = sb.reverse().toString();
if (onlyLettersSentence.equals(onlyLettersSentenceReverse)) {
return true;
}
return false;
}
public static void main(String[] args) {
// Test 1
System.out.println("Test 1: " + isPalindromeIgnoreCasePRO(""));
// Test 2
System.out.println("Test 2: " + isPalindromeIgnoreCasePRO("Red rum, sir, is murder!"));
// Test 3
System.out.println("Test 3: " + isPalindromeIgnoreCasePRO("Was it a cat I saw?"));
// Test 4
System.out.println("Test 4: " + isPalindromeIgnoreCasePRO("Not a palindrom, I'm afraid.."));
// Test 5
System.out.println("Test 5: " + isPalindromeIgnoreCasePRO("Step on no pets."));
}
}
Acest exercițiu exploatează noțiunile de bază de OOP, predate în cadrul Modulului pentru Începători, conform programei de studiu.
În cadrul rezolvării fiecărui subpunct, este important să ții cont de restricțiile și detaliile de implementare ale subpunctelor anterioare, astfel încât să obții o clasă funcțională, coerentă și bine structurată. Recomandarea noastră este să citești inițial toată cerința pentru a-ți forma o privire de ansamblu asupra clasei de proiectat și abia ulterior să începi rezolvarea, cu primele subpuncte.
Cerință
Implementează o clasă GenericPackage
, folosită de un sistem de curierat, conform următoarelor detalii de implementare:
Starea internă este reprezentată astfel:
uniqueID
: cod unic de identificare a pachetului, format numai din cifre, de tipul String
.
weight
: greutatea coletului, de tipul double
.
packageName
: numele pachetului, de tipul String
.
courierName
: numele firmei de curierat, tipul String
.
Clasa GenericPackage
trebuie să respecte următoarele criterii:
deoarece clasa va fi folosită de un singur curier, toate obiectele clasei GenericPackage
vor avea același courierName
.
câmpul uniqueID
, unic pentru fiecare obiect GenericPackage
, trebuie să nu poată fi modificat (i.e. după inițializarea acestuia).
transformă câmpul courierName
, același pentru toate obiectele din clasă, într-o proprietate a obiectelor, care poate fi atât citită cât și actualizată.
transformă câmpul packageName
într-o proprietate read-only (i.e. poate fi citită, dar nu poate fi actualizată).
definește 2 constructori diferiți ai clasei, la alegere.
Definește următoarele metode:
addItem(double itemWeight)
: actualizează greutatea pachetului prin adăugarea greutății noului obiect (i.e. itemWeight
) la greutatea actuală a coletului.
checkID()
: metoda verifică dacă numărul pachetului este valid. Codul unic de identificare este valid dacă sunt îndeplinite toate condițiile următoare:
codul este alcătuit doar din cifre (i.e. toate caracterele sunt cifre).
numărul de cifre impare este multiplu de 3
.
suma tuturor cifrelor formează un număr divizibil cu 4
.
diferența dintre oricare 2 cifre consecutive din cod este mai mică decât 5
.
lungimea totală a codului este cuprinsă între 10
și 12
caractere (inclusiv).
computeDetails()
metoda returnează un obiect String
, care conține detaliile obiectului, sub următorul format:
Pachetul <packageName> avand codul <uniqueID> si greutatea <weight> apartine curierului <courierName>.
Exemplu: Pachetul LaptopDustPRO avand codul 213142341425 si greutatea 4.2 apartine curierului DevCarry.
Soluție
- GenericPackage.java
package examen;
public class GenericPackage {
// 4.1 Toate campurile:
private final String uniqueID; // 4.2.b. adaugare 'final'
private double weight;
private String packageName;
private static String courierName; // 4.2.a. adaugare 'static'
// 4.2.c: 'getter' + 'setter' pentru 'courierName'
// Obs: ambele metode sunt statice deoarece nu lucreaza cu campurile obiectului,
// ci doar cu campurile clasei (i.e. statice)
public static String getCourierName() {
return courierName;
}
public static void setCourierName(String courierName) {
GenericPackage.courierName = courierName;
}
//4.2.d: doar 'getter' pentru 'packageName',
// deoarece proprietatea poate fi *doar citita* (read-only)
public String getPackageName() {
return packageName;
}
// 4.2.e: ambii constructori trebuie sa initializeze orice
// camp 'final'. Altfel constructorii nu sunt valizi.
// => ambii constructori vor initializa obligatoriu 'uniqueID'
public GenericPackage(String uniqueID, double weight, String packageName) {
this.uniqueID = uniqueID;
this.weight = weight;
this.packageName = packageName;
}
public GenericPackage(String uniqueID, String packageName) {
this(uniqueID, -1, packageName);
}
// 4.3.a
public void addItem(double itemWeight) {
this.weight += itemWeight;
}
// 4.3.b
public boolean checkID() {
// Avantajul abordarii: in momentul in care s-a gasit o conditie
// 'false', niciuna dintre conditiile urmatoare nu mai este testata
if (this.idCondition1() && this.idCondition2() && this.idCondition3()
&& this.idCondition4() && this.idCondition5()) {
return true;
}
return false;
}
// 4.3.b - metoda auxiliara
// (-> va fi 'private')
private boolean idCondition1() {
for (int i = 0; i < this.uniqueID.length(); i++) {
if (Character.isDigit(uniqueID.charAt(i)) == false) {
return false;
}
}
return true;
}
// 4.3.b - metoda auxiliara
// (-> va fi 'private')
private boolean idCondition2() {
int counter = 0;
for (int i = 0; i < this.uniqueID.length(); i++) {
int curentDigit = Character.getNumericValue(uniqueID.charAt(i));
if (curentDigit % 2 == 1) {
counter++;
}
}
if (counter % 3 == 0) {
return true;
}
return false;
}
// 4.3.b - metoda auxiliara
// (-> va fi 'private')
private boolean idCondition3() {
int sum = 0;
for (int i = 0; i < this.uniqueID.length(); i++) {
int curentDigit = Character.getNumericValue(uniqueID.charAt(i));
sum += curentDigit;
}
if (sum % 4 == 0) {
return true;
}
return false;
}
// 4.3.b - metoda auxiliara
// (-> va fi 'private')
private boolean idCondition4() {
for (int i = 0; i < this.uniqueID.length() - 1; i++) {
int curentDigit = Character.getNumericValue(uniqueID.charAt(i));
int nextDigit = Character.getNumericValue(uniqueID.charAt(i + 1));
int diff = curentDigit - nextDigit;
if (diff >= 5 || diff <= -5) { // include cazul cand diferenta este negativa
return false;
}
}
return true;
}
// 4.3.b - metoda auxiliara
// (-> va fi 'private')
private boolean idCondition5() {
if (uniqueID.length() >= 10 && uniqueID.length() <= 12) {
return true;
}
return false;
}
// 4.3.c
public String computeDetails() {
String toString = "Pachetul " + this.packageName + " avand codul "
+ this.uniqueID + " si greutatea " + this.weight
+ " apartine curierului " + this.courierName + ".";
return toString;
}
}
Scenariu de testare:
În continuare, este prezentată o scurtă secvență de cod care testează implementarea clasei definite anterior. Această secțiune, precum și Output-ul său nu trebuie scrise în cadrul rezolvării exercițiului. Motivul pentru care sunt prezentate aici este să te ajute să testezi implementarea în cadrul pregătirii pentru interviu și să observi un posibil scenariu de utilizare.
- Test.java
package examen;
public class Test {
public static void main(String[] args) {
GenericPackage.setCourierName("DevCourier");
GenericPackage gp = new GenericPackage("25374525762", 0.413, "Diplome");
gp.addItem(20.0d);
System.out.println(gp.checkID());
System.out.println(gp.computeDetails());
}
}
Output
true
Pachetul Diplome avand codul 25374525762 si greutatea 20.413, apartine curierului DevCourier.
Câmp util pentru Arrays
:
Câmp | Descriere |
length | Stochează dimensiunea (i.e. numărul de elemente) al unui Array . |
Metode utile ale clasei String
:
Metodă | Descriere |
int length() | Returnează lungimea șirului de caractere stocat în obiectul de tip String . |
int indexOf(int ch) | Returnează indexul primei, respectiv ultimei apariții din șir a caracterului ch . |
int lastIndexOf(int ch) |
int indexOf(int ch, int fromIndex) | Similar cu funcționalitatea anterioară
- doar că în acest caz căutarea începe de la un anumit index (i.e. fromIndex ). |
int lastIndexOf(int ch, int fromIndex) |
int indexOf(String str) | Returnează indexul primei, respectiv ultimei apariții din șir a șirului str . |
int lastIndexOf(String str) |
int indexOf(String str, int fromIndex) | Similar cu funcționalitatea anterioară
- doar că în acest caz, căutarea începe de la un anumit index (i.e. fromIndex ). |
int lastIndexOf(String str, int fromIndex) |
boolean contains(CharSequence s) | Metoda returnează true dacă a fost găsit subșirul căutat în șir, și false altfel. |
Clasa wrapper Character
:
Metodă | Descriere |
static int getNumericValue(char ch) | Returnează valoarea numerică echivalentă (i.e. de tipul int a caracterului ch ). |
static boolean isDigit(char ch) | Returnează true dacă ch este o cifră, și false altfel. |
static boolean isLetter(char ch) | Returnează true dacă ch este o literă, și false altfel. |
static boolean isLetterOrDigit(char ch) | Returnează true dacă ch este o literă sau o cifră, și false altfel. |
Pentru întrebări sau orice nelămuriri folosește forum-ul de mai jos sau trimite-ne un email la office@devmind.ro.