├── Books ├── کتاب اول ساختمان داده و الگوریتم با جاوا.docx ├── کتاب دوم جاوا برای مهندسان نرم‌افزار.docx ├── کتاب سوم معماری نرم‌افزار و سیستم دیزاین با جاوا.docx ├── کتاب ششم تست، خطایابی و بهینه‌سازی نرم‌افزار در جاوا.docx ├── کتاب هفتم دوآپس و پیاده‌سازی نرم‌افزارهای جاوا در مقیاس بزرگ.docx ├── کتاب پنجم امنیت نرم‌افزار در جاوا.docx └── کتاب چهارم الگوهای طراحی در جاوا.docx ├── CalcMortgage ├── CalcMortgage.iml ├── out │ └── production │ │ └── CalcMortgage │ │ ├── MortgageApp.class │ │ └── MortgageCalculator.class └── src │ └── MortgageApp.java ├── Loan Interest Rate Calculator Project ├── Loan Interest Rate Calculator Project.iml ├── out │ └── production │ │ └── first │ │ └── Main.class └── src │ └── Main.java ├── Mini Projects ├── CalcMortgage │ ├── CalcMortgage.iml │ ├── out │ │ └── production │ │ │ └── CalcMortgage │ │ │ ├── MortgageApp.class │ │ │ └── MortgageCalculator.class │ └── src │ │ └── MortgageApp.java └── Loan Interest Rate Calculator Project │ ├── Loan Interest Rate Calculator Project.iml │ ├── out │ └── production │ │ └── first │ │ └── Main.class │ └── src │ └── Main.java ├── OCP ├── OCP.iml ├── README.md ├── out │ └── production │ │ └── OCP │ │ ├── Client.class │ │ ├── DistinctionDecider.class │ │ ├── Main.class │ │ └── Student.class └── src │ ├── ArtsDistinctionDecider.java │ ├── ArtsStudent.java │ ├── Client.java │ ├── DistinctionDecider.java │ ├── ScienceDistinctionDecider.java │ ├── ScienceStudent.java │ └── Student.java ├── README.md ├── RoadMap └── RoadMap.md ├── SOLID Principle ├── OCP │ ├── OCP.iml │ ├── README.md │ ├── out │ │ └── production │ │ │ └── OCP │ │ │ ├── Client.class │ │ │ ├── DistinctionDecider.class │ │ │ ├── Main.class │ │ │ └── Student.class │ └── src │ │ ├── ArtsDistinctionDecider.java │ │ ├── ArtsStudent.java │ │ ├── Client.java │ │ ├── DistinctionDecider.java │ │ ├── ScienceDistinctionDecider.java │ │ ├── ScienceStudent.java │ │ └── Student.java └── SRP │ ├── SRP.iml │ ├── out │ └── production │ │ └── SRP │ │ ├── Client.class │ │ ├── Employee.class │ │ └── Main.class │ └── src │ ├── Client.java │ ├── Employee.java │ ├── EmployeeIdGenerator.java │ ├── Main.java │ └── SeniorityChecker.java ├── SRP ├── SRP.iml ├── out │ └── production │ │ └── SRP │ │ ├── Client.class │ │ ├── Employee.class │ │ └── Main.class └── src │ ├── Client.java │ ├── Employee.java │ ├── EmployeeIdGenerator.java │ ├── Main.java │ └── SeniorityChecker.java └── Steps ├── FirstChapter.md ├── FirstDay.md ├── FourDayOOP.md ├── SecondDay.md └── ThirdDay.md /Books/کتاب اول ساختمان داده و الگوریتم با جاوا.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/Books/کتاب اول ساختمان داده و الگوریتم با جاوا.docx -------------------------------------------------------------------------------- /Books/کتاب دوم جاوا برای مهندسان نرم‌افزار.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/Books/کتاب دوم جاوا برای مهندسان نرم‌افزار.docx -------------------------------------------------------------------------------- /Books/کتاب سوم معماری نرم‌افزار و سیستم دیزاین با جاوا.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/Books/کتاب سوم معماری نرم‌افزار و سیستم دیزاین با جاوا.docx -------------------------------------------------------------------------------- /Books/کتاب ششم تست، خطایابی و بهینه‌سازی نرم‌افزار در جاوا.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/Books/کتاب ششم تست، خطایابی و بهینه‌سازی نرم‌افزار در جاوا.docx -------------------------------------------------------------------------------- /Books/کتاب هفتم دوآپس و پیاده‌سازی نرم‌افزارهای جاوا در مقیاس بزرگ.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/Books/کتاب هفتم دوآپس و پیاده‌سازی نرم‌افزارهای جاوا در مقیاس بزرگ.docx -------------------------------------------------------------------------------- /Books/کتاب پنجم امنیت نرم‌افزار در جاوا.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/Books/کتاب پنجم امنیت نرم‌افزار در جاوا.docx -------------------------------------------------------------------------------- /Books/کتاب چهارم الگوهای طراحی در جاوا.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/Books/کتاب چهارم الگوهای طراحی در جاوا.docx -------------------------------------------------------------------------------- /CalcMortgage/CalcMortgage.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /CalcMortgage/out/production/CalcMortgage/MortgageApp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/CalcMortgage/out/production/CalcMortgage/MortgageApp.class -------------------------------------------------------------------------------- /CalcMortgage/out/production/CalcMortgage/MortgageCalculator.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/CalcMortgage/out/production/CalcMortgage/MortgageCalculator.class -------------------------------------------------------------------------------- /CalcMortgage/src/MortgageApp.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | import java.text.NumberFormat; 3 | 4 | // Class to calculate mortgage payments 5 | class MortgageCalculator { 6 | private final double principal; // Loan amount 7 | private final double annualInterestRate; // Annual interest rate 8 | private final int years; // Loan term in years 9 | 10 | // Constructor to initialize mortgage details 11 | public MortgageCalculator(double principal, double annualInterestRate, int years) { 12 | this.principal = principal; 13 | this.annualInterestRate = annualInterestRate; 14 | this.years = years; 15 | } 16 | 17 | // Method to calculate monthly mortgage payment 18 | public double calculateMonthlyPayment() { 19 | double monthlyInterestRate = (annualInterestRate / 100) / 12; // Convert annual interest rate to monthly 20 | int numberOfPayments = years * 12; // Total number of monthly payments 21 | 22 | return (principal * monthlyInterestRate * Math.pow(1 + monthlyInterestRate, numberOfPayments)) / 23 | (Math.pow(1 + monthlyInterestRate, numberOfPayments) - 1); 24 | } 25 | 26 | // Method to display remaining balance after each month 27 | public void displayRemainingBalance() { 28 | double monthlyPayment = calculateMonthlyPayment(); 29 | double monthlyInterestRate = (annualInterestRate / 100) / 12; 30 | double remainingBalance = principal; 31 | int numberOfPayments = years * 12; 32 | 33 | System.out.println("\nPayment Schedule:"); 34 | for (int month = 1; month <= numberOfPayments; month++) { 35 | double interest = remainingBalance * monthlyInterestRate; // Interest portion of payment 36 | double principalPayment = monthlyPayment - interest; // Principal portion of payment 37 | remainingBalance -= principalPayment; // Reduce remaining balance 38 | 39 | if (remainingBalance < 0) remainingBalance = 0; // Ensure balance does not go negative 40 | 41 | System.out.println("Month " + month + ": " + NumberFormat.getCurrencyInstance().format(remainingBalance)); 42 | } 43 | } 44 | } 45 | 46 | // Main application to interact with user 47 | public class MortgageApp { 48 | public static void main(String[] args) { 49 | Scanner scanner = new Scanner(System.in); 50 | 51 | // Default values 52 | double defaultPrincipal = 100000; 53 | double defaultAnnualInterestRate = 5.0; 54 | int defaultYears = 30; 55 | 56 | // Get loan details from user (or use default values) 57 | System.out.print("Enter loan amount (default: " + defaultPrincipal + "): "); 58 | String principalInput = scanner.nextLine(); 59 | double principal = principalInput.isEmpty() ? defaultPrincipal : Double.parseDouble(principalInput); 60 | 61 | System.out.print("Enter annual interest rate (default: " + defaultAnnualInterestRate + "): "); 62 | String interestInput = scanner.nextLine(); 63 | double annualInterestRate = interestInput.isEmpty() ? defaultAnnualInterestRate : Double.parseDouble(interestInput); 64 | 65 | System.out.print("Enter loan term in years (default: " + defaultYears + "): "); 66 | String yearsInput = scanner.nextLine(); 67 | int years = yearsInput.isEmpty() ? defaultYears : Integer.parseInt(yearsInput); 68 | 69 | // Create MortgageCalculator instance and calculate payment 70 | MortgageCalculator calculator = new MortgageCalculator(principal, annualInterestRate, years); 71 | double monthlyPayment = calculator.calculateMonthlyPayment(); 72 | 73 | // Format and display monthly payment 74 | String formattedPayment = NumberFormat.getCurrencyInstance().format(monthlyPayment); 75 | System.out.println("Monthly Payment: " + formattedPayment); 76 | 77 | // Display payment schedule 78 | calculator.displayRemainingBalance(); 79 | 80 | scanner.close(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Loan Interest Rate Calculator Project/Loan Interest Rate Calculator Project.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Loan Interest Rate Calculator Project/out/production/first/Main.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/Loan Interest Rate Calculator Project/out/production/first/Main.class -------------------------------------------------------------------------------- /Loan Interest Rate Calculator Project/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.text.NumberFormat; 2 | import java.util.Scanner; 3 | 4 | public class Main { 5 | public static void main(String[] args) { 6 | final byte MONTH_IN_YEAR = 12; 7 | final byte PERCENT = 100; 8 | 9 | Scanner scanner = new Scanner(System.in); 10 | System.out.println("Principle: "); 11 | int principle = scanner.nextInt(); 12 | System.out.println("Annual Interest Rate: "); 13 | float annualintrest = scanner.nextFloat(); 14 | float monthlyintrest = annualintrest / PERCENT / MONTH_IN_YEAR; 15 | 16 | System.out.println("Period Year: "); 17 | byte years = scanner.nextByte(); 18 | int numberOfPeyments = years * MONTH_IN_YEAR; 19 | 20 | double montgage = principle * (monthlyintrest * Math.pow(1 + monthlyintrest, numberOfPeyments)) / 21 | (Math.pow(1 + monthlyintrest, numberOfPeyments) - 1); 22 | 23 | String montgageFormatted = NumberFormat.getCurrencyInstance().format(montgage); 24 | System.out.println("Montgage: " + montgageFormatted); 25 | 26 | } 27 | } -------------------------------------------------------------------------------- /Mini Projects/CalcMortgage/CalcMortgage.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Mini Projects/CalcMortgage/out/production/CalcMortgage/MortgageApp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/Mini Projects/CalcMortgage/out/production/CalcMortgage/MortgageApp.class -------------------------------------------------------------------------------- /Mini Projects/CalcMortgage/out/production/CalcMortgage/MortgageCalculator.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/Mini Projects/CalcMortgage/out/production/CalcMortgage/MortgageCalculator.class -------------------------------------------------------------------------------- /Mini Projects/CalcMortgage/src/MortgageApp.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | import java.text.NumberFormat; 3 | 4 | // Class to calculate mortgage payments 5 | class MortgageCalculator { 6 | private final double principal; // Loan amount 7 | private final double annualInterestRate; // Annual interest rate 8 | private final int years; // Loan term in years 9 | 10 | // Constructor to initialize mortgage details 11 | public MortgageCalculator(double principal, double annualInterestRate, int years) { 12 | this.principal = principal; 13 | this.annualInterestRate = annualInterestRate; 14 | this.years = years; 15 | } 16 | 17 | // Method to calculate monthly mortgage payment 18 | public double calculateMonthlyPayment() { 19 | double monthlyInterestRate = (annualInterestRate / 100) / 12; // Convert annual interest rate to monthly 20 | int numberOfPayments = years * 12; // Total number of monthly payments 21 | 22 | return (principal * monthlyInterestRate * Math.pow(1 + monthlyInterestRate, numberOfPayments)) / 23 | (Math.pow(1 + monthlyInterestRate, numberOfPayments) - 1); 24 | } 25 | 26 | // Method to display remaining balance after each month 27 | public void displayRemainingBalance() { 28 | double monthlyPayment = calculateMonthlyPayment(); 29 | double monthlyInterestRate = (annualInterestRate / 100) / 12; 30 | double remainingBalance = principal; 31 | int numberOfPayments = years * 12; 32 | 33 | System.out.println("\nPayment Schedule:"); 34 | for (int month = 1; month <= numberOfPayments; month++) { 35 | double interest = remainingBalance * monthlyInterestRate; // Interest portion of payment 36 | double principalPayment = monthlyPayment - interest; // Principal portion of payment 37 | remainingBalance -= principalPayment; // Reduce remaining balance 38 | 39 | if (remainingBalance < 0) remainingBalance = 0; // Ensure balance does not go negative 40 | 41 | System.out.println("Month " + month + ": " + NumberFormat.getCurrencyInstance().format(remainingBalance)); 42 | } 43 | } 44 | } 45 | 46 | // Main application to interact with user 47 | public class MortgageApp { 48 | public static void main(String[] args) { 49 | Scanner scanner = new Scanner(System.in); 50 | 51 | // Default values 52 | double defaultPrincipal = 100000; 53 | double defaultAnnualInterestRate = 5.0; 54 | int defaultYears = 30; 55 | 56 | // Get loan details from user (or use default values) 57 | System.out.print("Enter loan amount (default: " + defaultPrincipal + "): "); 58 | String principalInput = scanner.nextLine(); 59 | double principal = principalInput.isEmpty() ? defaultPrincipal : Double.parseDouble(principalInput); 60 | 61 | System.out.print("Enter annual interest rate (default: " + defaultAnnualInterestRate + "): "); 62 | String interestInput = scanner.nextLine(); 63 | double annualInterestRate = interestInput.isEmpty() ? defaultAnnualInterestRate : Double.parseDouble(interestInput); 64 | 65 | System.out.print("Enter loan term in years (default: " + defaultYears + "): "); 66 | String yearsInput = scanner.nextLine(); 67 | int years = yearsInput.isEmpty() ? defaultYears : Integer.parseInt(yearsInput); 68 | 69 | // Create MortgageCalculator instance and calculate payment 70 | MortgageCalculator calculator = new MortgageCalculator(principal, annualInterestRate, years); 71 | double monthlyPayment = calculator.calculateMonthlyPayment(); 72 | 73 | // Format and display monthly payment 74 | String formattedPayment = NumberFormat.getCurrencyInstance().format(monthlyPayment); 75 | System.out.println("Monthly Payment: " + formattedPayment); 76 | 77 | // Display payment schedule 78 | calculator.displayRemainingBalance(); 79 | 80 | scanner.close(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Mini Projects/Loan Interest Rate Calculator Project/Loan Interest Rate Calculator Project.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Mini Projects/Loan Interest Rate Calculator Project/out/production/first/Main.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/Mini Projects/Loan Interest Rate Calculator Project/out/production/first/Main.class -------------------------------------------------------------------------------- /Mini Projects/Loan Interest Rate Calculator Project/src/Main.java: -------------------------------------------------------------------------------- 1 | import java.text.NumberFormat; 2 | import java.util.Scanner; 3 | 4 | public class Main { 5 | public static void main(String[] args) { 6 | final byte MONTH_IN_YEAR = 12; 7 | final byte PERCENT = 100; 8 | 9 | Scanner scanner = new Scanner(System.in); 10 | System.out.println("Principle: "); 11 | int principle = scanner.nextInt(); 12 | System.out.println("Annual Interest Rate: "); 13 | float annualintrest = scanner.nextFloat(); 14 | float monthlyintrest = annualintrest / PERCENT / MONTH_IN_YEAR; 15 | 16 | System.out.println("Period Year: "); 17 | byte years = scanner.nextByte(); 18 | int numberOfPeyments = years * MONTH_IN_YEAR; 19 | 20 | double montgage = principle * (monthlyintrest * Math.pow(1 + monthlyintrest, numberOfPeyments)) / 21 | (Math.pow(1 + monthlyintrest, numberOfPeyments) - 1); 22 | 23 | String montgageFormatted = NumberFormat.getCurrencyInstance().format(montgage); 24 | System.out.println("Montgage: " + montgageFormatted); 25 | 26 | } 27 | } -------------------------------------------------------------------------------- /OCP/OCP.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /OCP/README.md: -------------------------------------------------------------------------------- 1 | The Student class and DistinctionDecider are both unchanged for any future changes in the distinction criteria.
2 | They are closed for modification.
3 | • Notice that every participant follows the SRP.
4 | • Suppose you need to consider a new stream, say commerce.
5 | Then you can create a new class such as CommerceStudent.
6 | Notice that in a case like this, you do not need to touch the ArtsStudent or ScienceStudent classes.
7 | • Similarly, when you consider different evaluation criteria for a different stream such as commerce, 8 | you can add a new derived class such as CommerceDistinctionDecider 9 | that implements the DistinctionDecider interface and you can set new distinction criteria for commerce students. 10 | In this case, you do not need to alter any existing class in the DistinctionDecider hierarchy.
11 | Obviously, the client code needs to adopt this change.
12 | • Using this approach, you avoid an if-else chain (shown in demonstration 3).
13 | This chain could grow if you consider new streams such as commerce following the approach that is shown in demonstration 14 | 3. Remember that avoiding a big if-else chain is always considered a better practice.
15 | It is because avoiding the if-else chains lowers the cyclomatic complexity of a program and produces better code.
16 | (Cyclomatic complexity is a software metric to indicate the complexity of a program. 17 | It indicates the number of paths through a particular piece of code.
18 | So, in simple terms, by lowering the cyclomatic complexity you make your code easily readable and testable.)
19 | I’ll finish this section with Robert C. Martin’s suggestion.
20 | In his book Clean Architecture, he gave us a simple formula:
21 | if you want component A to protect from component B, component B should depend on component 22 | A. But why do we give component A such importance? 23 | It is because we may want to put the most important rules in it. 24 | It is time to study the next principle. 25 | -------------------------------------------------------------------------------- /OCP/out/production/OCP/Client.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/OCP/out/production/OCP/Client.class -------------------------------------------------------------------------------- /OCP/out/production/OCP/DistinctionDecider.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/OCP/out/production/OCP/DistinctionDecider.class -------------------------------------------------------------------------------- /OCP/out/production/OCP/Main.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/OCP/out/production/OCP/Main.class -------------------------------------------------------------------------------- /OCP/out/production/OCP/Student.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/OCP/out/production/OCP/Student.class -------------------------------------------------------------------------------- /OCP/src/ArtsDistinctionDecider.java: -------------------------------------------------------------------------------- 1 | class ArtsDistinctionDecider implements DistinctionDecider{ 2 | @Override 3 | public void evaluateDistinction(Student student) { 4 | if (student.score > 70) { System.out.println(student.regNumber+" has received a distinction in arts."); 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /OCP/src/ArtsStudent.java: -------------------------------------------------------------------------------- 1 | public class ArtsStudent extends Student { 2 | public ArtsStudent(String name, 3 | String regNumber, 4 | double score, 5 | String dept) { 6 | super(name, regNumber, score); 7 | this.department = dept; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /OCP/src/Client.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; import java.util.List; 2 | class Client { 3 | public static void main(String[] args) { 4 | System.out.println("*** A demo that follows the OCP.***"); 5 | List scienceStudents = enrollScienceStudents(); 6 | List artsStudents = enrollArtsStudents(); 7 | // Display all results. System.out.println("===Results:==="); 8 | for (Student student : scienceStudents) { System.out.println(student); 9 | } 10 | for (Student student : artsStudents) { 11 | System.out.println(student); } 12 | // Evaluate distinctions. 13 | DistinctionDecider scienceDistinctionDecider = 14 | new ScienceDistinctionDecider(); 15 | DistinctionDecider artsDistinctionDecider = 16 | new ArtsDistinctionDecider(); 17 | System.out.println("===Distinctions:==="); for (Student student : scienceStudents) { 18 | scienceDistinctionDecider.evaluateDistinction(student); } 19 | for (Student student : artsStudents) { artsDistinctionDecider.evaluateDistinction(student); 20 | } 21 | } 22 | private static List enrollScienceStudents() { 23 | Student sam = new ScienceStudent("Sam","R1",81.5,"Comp.Sc."); 24 | Student bob = new ScienceStudent("Bob","R2",72,"Physics"); 25 | List scienceStudents = new ArrayList<>(); scienceStudents.add(sam); 26 | scienceStudents.add(bob); 27 | return scienceStudents; 28 | } 29 | private static List enrollArtsStudents() { 30 | Student john = new ArtsStudent("John", "R3", 71,"History"); 31 | Student kate = new ArtsStudent("Kate", "R4", 66.5,"English"); 32 | List artsStudents = new ArrayList<>(); artsStudents.add(john); 33 | artsStudents.add(kate); 34 | return artsStudents; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /OCP/src/DistinctionDecider.java: -------------------------------------------------------------------------------- 1 | interface DistinctionDecider { 2 | void evaluateDistinction(Student student); 3 | } -------------------------------------------------------------------------------- /OCP/src/ScienceDistinctionDecider.java: -------------------------------------------------------------------------------- 1 | class ScienceDistinctionDecider implements DistinctionDecider{ 2 | @Override 3 | public void evaluateDistinction(Student student) { if (student.score > 80) { 4 | System.out.println(student.regNumber+" has received a distinction in science."); 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /OCP/src/ScienceStudent.java: -------------------------------------------------------------------------------- 1 | class ScienceStudent extends Student{ 2 | public ScienceStudent(String name, 3 | String regNumber, 4 | double score, 5 | String dept) { 6 | super(name, regNumber, score); 7 | this.department = dept; 8 | } 9 | } -------------------------------------------------------------------------------- /OCP/src/Student.java: -------------------------------------------------------------------------------- 1 | abstract class Student { 2 | String name; 3 | String regNumber; 4 | double score; 5 | String department; 6 | public Student(String name, 7 | String regNumber, 8 | double score) { this.name = name; 9 | this.regNumber = regNumber; 10 | this.score = score; } 11 | @Override 12 | public String toString() { return ("Name: " + name + 13 | "\nReg Number: " + regNumber + "\nDept:" + department + "\nMarks:"+ score + "\n*******"); 14 | } 15 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Java Tutorial 2 | 3 | I am in the process of learning Java with a focus on System Design and Software Architecture. My primary goal is to understand how Java can be applied effectively in these areas, especially for those with experience in other programming languages who are just starting to learn Java.
4 | To support this, I’ve created a repository to share the resources and materials I am working through. This repository aims to help those who are new to Java but have a background in software engineering, system design, architecture, and security. 5 | The content is organized into four main sections: 6 |
7 |
8 | **Software Engineering** - Key concepts and best practices in software development using Java.
9 | **System Design** - Exploring system design patterns, scalability, and how to implement them in Java.
10 | **Architecture** - Understanding Java's role in building robust and scalable architectures.
11 | **Design Patterns** - Design patterns are reusable solutions to common software design problems. In Java, patterns like Singleton, Factory, Observer, and Strategy help solve issues related to object creation, state management, and algorithm flexibility. Understanding these patterns helps Java developers write maintainable and scalable code.
12 | **Data Engineering** - How to manage datas in structures in Data Flows ...
13 | **Distributed Systems** - Connect all puzzle that you build at the first of the way.
14 | **Best Practices** - Best practices in Java include writing clean, readable code by adhering to conventions like naming standards, avoid hardcoding, and using SOLID principles. Additionally, leveraging dependency injection (via Spring), keeping code modular, and performing code reviews are key strategies to ensure maintainability and scalability in large Java systems.
15 | **Security** - Focusing on secure coding practices, encryption, and other security considerations within Java applications.
16 | **Microservices** - Microservices in Java involve breaking down a monolithic application into small, independently deployable services. Using frameworks like Spring Boot and Spring Cloud, developers can build scalable, maintainable systems where each service is responsible for a specific business function and communicates over lightweight protocols like HTTP or messaging queues.
17 | **Test & Debug** - Testing and debugging in Java are essential for building reliable software. JUnit and Mockito are commonly used for unit and integration testing, while JUnit 5 provides more powerful features like parameterized tests. Debugging tools like JVisualVM, YourKit, and Eclipse Debugger help track issues related to memory leaks, performance bottlenecks, and concurrency problems.
18 | I hope this repository will be useful for anyone transitioning to Java from other programming languages, and will serve as a helpful resource for learning and applying Java in these key areas. 19 | 20 | 21 | ## Youtube Sources: 22 | https://www.youtube.com/playlist?list=PLTEzTFAAzxQ4M8vt1I9OUxPtB9mgK_Spz 23 | 24 | ## Github Repository: 25 | https://github.com/JavaBaz/presentations 26 | 27 | ## Book Sources: 28 | 1. Vaskaran Sarcar - Java Design Patterns A Hands-On Experience with Real-World Examples (2022, Apress)
29 | 2. Olaf Musch - Design Patterns with Java An Introduction (2023, Springer Vieweg)
30 | 3. Miroslav Wengner - Practical Design Patterns for Java Developers_ Hone your software design skills by implementing popular design patterns in Java (2023, Packt Publishing)
31 | 4. Mohammed Moreb - Design and Implementation of Software Engineering for Modern Web Applications (2024, IGI Global)
32 | 5. Dayang Norhayati A. Jawawi, Imran Sarwar Bajwa, Rafaqut Kazmi - Engineering Software for Modern Challenges First International Conference
33 | 6. Martin P. Robillard - Introduction to Software Design with Java (2022, Springer)
34 | 7. David Farley - Modern Software Engineering (2022, Addison-Wesley)
35 | 8. Benjamin Evans, Martijn Verburg, Jason Clark - The Well-Grounded Java Developer (2022, Manning Publications)
36 | 9. Titus Winters, Tom Manshreck, Hyrum Wright - Software Engineering at Google_ Lessons Learned from Programming Over Time (2020, O'Reilly Media)
37 | 10. Sarvesh Pandey, Udai Shanker, Vijayalakshmi Saravanan, Rajinikum - Role of Data-Intensive Distributed Computing Systems in Designing Data Solutions (2023, Springer)
38 | 11. Brendan Burns - Designing Distributed Systems (2025, O’Reilly Media)
39 | 12. Zhiyong Tan - Acing the System Design Interview (2024, Manning Publications)
40 | 13. Alex Xu - System Design Interview_ An Insider’s Guide (June 12, 2020)
41 | 14. Fernández, Javier González - Java 9 Concurrency Cookbook (2017)
42 | 15. Ian F. Darwin - Java Cookbook_ Problems and Solutions for Java Developers (2020, O’Reilly Media)
43 | 16. Ian F. Darwin - Darwin Java Cookbook (2014, O'Reilly Media)
44 | -------------------------------------------------------------------------------- /RoadMap/RoadMap.md: -------------------------------------------------------------------------------- 1 | 1. **Java** 2 | 2. **Learn the Fundamentals** 3 | * **Basic Syntax** 4 | * **DataTypes, Variables** 5 | * **Conditionals** 6 | * **Loops** (implied in "Functions Working with Files and APIsLoops") 7 | * **Functions Working with Files and APIs** 8 | * **OOP, Interfaces, Classes** 9 | * **Packages** 10 | * **DataStructures** 11 | 3. **Getting Deeper** 12 | * **How JVM works?** 13 | * **Garbage Collection** 14 | * **Memory Management** (implied in "Exception Handling Memory Management") 15 | * **Basics of Threads** 16 | * **Exception Handling** 17 | * **Collection Framework** 18 | * **Generics** 19 | * **Streams Serialization** 20 | * **Networking & Sockets** 21 | 4. **Build Tools** 22 | * **Maven** 23 | * **Gradle** 24 | * **Ant** 25 | 5. **Testing your Apps** 26 | * **Unit Testing** 27 | * **JUnit** 28 | * **TestNG** 29 | * **Mocking** 30 | * **Mockito> Behavior Testing** 31 | * **Integration Testing** 32 | * **REST Assured** 33 | * **Performance Testing** (implied by **JMeter**) 34 | * **JMeter** 35 | * **Behavior-Driven Development** (implied by **Cucumber-JVM** and **Cukes JBehave**) 36 | * **Cucumber-JVM** 37 | * **Cukes JBehave** 38 | 6. **Web Frameworks** 39 | * **Spring** 40 | * **Spring Boot** 41 | * **Play Framework** 42 | * **Spark** 43 | 7. **ORM (Object-Relational Mapping)** 44 | * **JPA (Java Persistence API)** 45 | * **Hibernate** 46 | * **Spring Data JPA** 47 | * **EBean** 48 | 8. **Data Access** 49 | * **JDBC** 50 | * **JDBI3** 51 | * **JDBC Template** 52 | 9. **Logging Frameworks** 53 | * **Log4j2** 54 | * **Logback** 55 | * **TinyLog** 56 | 10. **Backend Roadmap** 57 | * **Backend Roadmap till Language Selection** 58 | * **TestNG Backend Roadmap after Language Selection** 59 | -------------------------------------------------------------------------------- /SOLID Principle/OCP/OCP.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SOLID Principle/OCP/README.md: -------------------------------------------------------------------------------- 1 | The Student class and DistinctionDecider are both unchanged for any future changes in the distinction criteria.
2 | They are closed for modification.
3 | • Notice that every participant follows the SRP.
4 | • Suppose you need to consider a new stream, say commerce.
5 | Then you can create a new class such as CommerceStudent.
6 | Notice that in a case like this, you do not need to touch the ArtsStudent or ScienceStudent classes.
7 | • Similarly, when you consider different evaluation criteria for a different stream such as commerce, 8 | you can add a new derived class such as CommerceDistinctionDecider 9 | that implements the DistinctionDecider interface and you can set new distinction criteria for commerce students. 10 | In this case, you do not need to alter any existing class in the DistinctionDecider hierarchy.
11 | Obviously, the client code needs to adopt this change.
12 | • Using this approach, you avoid an if-else chain (shown in demonstration 3).
13 | This chain could grow if you consider new streams such as commerce following the approach that is shown in demonstration 14 | 3. Remember that avoiding a big if-else chain is always considered a better practice.
15 | It is because avoiding the if-else chains lowers the cyclomatic complexity of a program and produces better code.
16 | (Cyclomatic complexity is a software metric to indicate the complexity of a program. 17 | It indicates the number of paths through a particular piece of code.
18 | So, in simple terms, by lowering the cyclomatic complexity you make your code easily readable and testable.)
19 | I’ll finish this section with Robert C. Martin’s suggestion.
20 | In his book Clean Architecture, he gave us a simple formula:
21 | if you want component A to protect from component B, component B should depend on component 22 | A. But why do we give component A such importance? 23 | It is because we may want to put the most important rules in it. 24 | It is time to study the next principle. 25 | -------------------------------------------------------------------------------- /SOLID Principle/OCP/out/production/OCP/Client.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/SOLID Principle/OCP/out/production/OCP/Client.class -------------------------------------------------------------------------------- /SOLID Principle/OCP/out/production/OCP/DistinctionDecider.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/SOLID Principle/OCP/out/production/OCP/DistinctionDecider.class -------------------------------------------------------------------------------- /SOLID Principle/OCP/out/production/OCP/Main.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/SOLID Principle/OCP/out/production/OCP/Main.class -------------------------------------------------------------------------------- /SOLID Principle/OCP/out/production/OCP/Student.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/SOLID Principle/OCP/out/production/OCP/Student.class -------------------------------------------------------------------------------- /SOLID Principle/OCP/src/ArtsDistinctionDecider.java: -------------------------------------------------------------------------------- 1 | class ArtsDistinctionDecider implements DistinctionDecider{ 2 | @Override 3 | public void evaluateDistinction(Student student) { 4 | if (student.score > 70) { System.out.println(student.regNumber+" has received a distinction in arts."); 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /SOLID Principle/OCP/src/ArtsStudent.java: -------------------------------------------------------------------------------- 1 | public class ArtsStudent extends Student { 2 | public ArtsStudent(String name, 3 | String regNumber, 4 | double score, 5 | String dept) { 6 | super(name, regNumber, score); 7 | this.department = dept; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SOLID Principle/OCP/src/Client.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; import java.util.List; 2 | class Client { 3 | public static void main(String[] args) { 4 | System.out.println("*** A demo that follows the OCP.***"); 5 | List scienceStudents = enrollScienceStudents(); 6 | List artsStudents = enrollArtsStudents(); 7 | // Display all results. System.out.println("===Results:==="); 8 | for (Student student : scienceStudents) { System.out.println(student); 9 | } 10 | for (Student student : artsStudents) { 11 | System.out.println(student); } 12 | // Evaluate distinctions. 13 | DistinctionDecider scienceDistinctionDecider = 14 | new ScienceDistinctionDecider(); 15 | DistinctionDecider artsDistinctionDecider = 16 | new ArtsDistinctionDecider(); 17 | System.out.println("===Distinctions:==="); for (Student student : scienceStudents) { 18 | scienceDistinctionDecider.evaluateDistinction(student); } 19 | for (Student student : artsStudents) { artsDistinctionDecider.evaluateDistinction(student); 20 | } 21 | } 22 | private static List enrollScienceStudents() { 23 | Student sam = new ScienceStudent("Sam","R1",81.5,"Comp.Sc."); 24 | Student bob = new ScienceStudent("Bob","R2",72,"Physics"); 25 | List scienceStudents = new ArrayList<>(); scienceStudents.add(sam); 26 | scienceStudents.add(bob); 27 | return scienceStudents; 28 | } 29 | private static List enrollArtsStudents() { 30 | Student john = new ArtsStudent("John", "R3", 71,"History"); 31 | Student kate = new ArtsStudent("Kate", "R4", 66.5,"English"); 32 | List artsStudents = new ArrayList<>(); artsStudents.add(john); 33 | artsStudents.add(kate); 34 | return artsStudents; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /SOLID Principle/OCP/src/DistinctionDecider.java: -------------------------------------------------------------------------------- 1 | interface DistinctionDecider { 2 | void evaluateDistinction(Student student); 3 | } -------------------------------------------------------------------------------- /SOLID Principle/OCP/src/ScienceDistinctionDecider.java: -------------------------------------------------------------------------------- 1 | class ScienceDistinctionDecider implements DistinctionDecider{ 2 | @Override 3 | public void evaluateDistinction(Student student) { if (student.score > 80) { 4 | System.out.println(student.regNumber+" has received a distinction in science."); 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /SOLID Principle/OCP/src/ScienceStudent.java: -------------------------------------------------------------------------------- 1 | class ScienceStudent extends Student{ 2 | public ScienceStudent(String name, 3 | String regNumber, 4 | double score, 5 | String dept) { 6 | super(name, regNumber, score); 7 | this.department = dept; 8 | } 9 | } -------------------------------------------------------------------------------- /SOLID Principle/OCP/src/Student.java: -------------------------------------------------------------------------------- 1 | abstract class Student { 2 | String name; 3 | String regNumber; 4 | double score; 5 | String department; 6 | public Student(String name, 7 | String regNumber, 8 | double score) { this.name = name; 9 | this.regNumber = regNumber; 10 | this.score = score; } 11 | @Override 12 | public String toString() { return ("Name: " + name + 13 | "\nReg Number: " + regNumber + "\nDept:" + department + "\nMarks:"+ score + "\n*******"); 14 | } 15 | } -------------------------------------------------------------------------------- /SOLID Principle/SRP/SRP.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SOLID Principle/SRP/out/production/SRP/Client.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/SOLID Principle/SRP/out/production/SRP/Client.class -------------------------------------------------------------------------------- /SOLID Principle/SRP/out/production/SRP/Employee.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/SOLID Principle/SRP/out/production/SRP/Employee.class -------------------------------------------------------------------------------- /SOLID Principle/SRP/out/production/SRP/Main.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/SOLID Principle/SRP/out/production/SRP/Main.class -------------------------------------------------------------------------------- /SOLID Principle/SRP/src/Client.java: -------------------------------------------------------------------------------- 1 | public class Client { 2 | public static void main(String[] args) { 3 | System.out.println("*** A demo that follows the SRP.***"); 4 | 5 | Employee robin = new Employee("Robin", "Smith", 7.5); 6 | showEmpDetail(robin); 7 | 8 | System.out.println("\n*******\n"); 9 | 10 | Employee kevin = new Employee("Kevin", "Proctor", 3.2); 11 | showEmpDetail(kevin); 12 | } 13 | 14 | private static void showEmpDetail(Employee emp) { 15 | emp.displayEmpDetail(); 16 | 17 | EmployeeIdGenerator idGenerator = new EmployeeIdGenerator(); 18 | String empId = idGenerator.generateEmpId(emp.getFirstName()); 19 | System.out.println("The employee id: " + empId); 20 | 21 | SeniorityChecker seniorityChecker = new SeniorityChecker(); 22 | System.out.println("This employee is a " + 23 | seniorityChecker.checkSeniority(emp.getExperienceInYears()) + " employee."); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SOLID Principle/SRP/src/Employee.java: -------------------------------------------------------------------------------- 1 | class Employee { 2 | private String firstName; 3 | private String lastName; 4 | private double experienceInYears; 5 | 6 | public Employee(String firstName, String lastName, double experienceInYears) { 7 | this.firstName = firstName; 8 | this.lastName = lastName; 9 | this.experienceInYears = experienceInYears; 10 | } 11 | 12 | public String getFirstName() { 13 | return firstName; 14 | } 15 | 16 | public double getExperienceInYears() { 17 | return experienceInYears; 18 | } 19 | 20 | public void displayEmpDetail() { 21 | System.out.println("Employee: " + firstName + " " + lastName); 22 | System.out.println("Experience: " + experienceInYears + " years"); 23 | } 24 | } -------------------------------------------------------------------------------- /SOLID Principle/SRP/src/EmployeeIdGenerator.java: -------------------------------------------------------------------------------- 1 | class EmployeeIdGenerator { 2 | public String generateEmpId(String firstName) { 3 | return firstName.substring(0, 3).toUpperCase() + System.currentTimeMillis() % 1000; 4 | } 5 | } -------------------------------------------------------------------------------- /SOLID Principle/SRP/src/Main.java: -------------------------------------------------------------------------------- 1 | //TIP To Run code, press or 2 | // click the icon in the gutter. 3 | public class Main { 4 | public static void main(String[] args) { 5 | //TIP Press with your caret at the highlighted text 6 | // to see how IntelliJ IDEA suggests fixing it. 7 | System.out.printf("Hello and welcome!"); 8 | 9 | for (int i = 1; i <= 5; i++) { 10 | //TIP Press to start debugging your code. We have set one breakpoint 11 | // for you, but you can always add more by pressing . 12 | System.out.println("i = " + i); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /SOLID Principle/SRP/src/SeniorityChecker.java: -------------------------------------------------------------------------------- 1 | class SeniorityChecker { 2 | public String checkSeniority(double experienceInYears) { 3 | return experienceInYears > 5 ? "Senior" : "Junior"; 4 | } 5 | } -------------------------------------------------------------------------------- /SRP/SRP.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SRP/out/production/SRP/Client.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/SRP/out/production/SRP/Client.class -------------------------------------------------------------------------------- /SRP/out/production/SRP/Employee.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/SRP/out/production/SRP/Employee.class -------------------------------------------------------------------------------- /SRP/out/production/SRP/Main.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parsa-Parvizi/Java-Toturial/8c97ba4d30e6a6debccc4379ff0f2591a7ad8405/SRP/out/production/SRP/Main.class -------------------------------------------------------------------------------- /SRP/src/Client.java: -------------------------------------------------------------------------------- 1 | public class Client { 2 | public static void main(String[] args) { 3 | System.out.println("*** A demo that follows the SRP.***"); 4 | 5 | Employee robin = new Employee("Robin", "Smith", 7.5); 6 | showEmpDetail(robin); 7 | 8 | System.out.println("\n*******\n"); 9 | 10 | Employee kevin = new Employee("Kevin", "Proctor", 3.2); 11 | showEmpDetail(kevin); 12 | } 13 | 14 | private static void showEmpDetail(Employee emp) { 15 | emp.displayEmpDetail(); 16 | 17 | EmployeeIdGenerator idGenerator = new EmployeeIdGenerator(); 18 | String empId = idGenerator.generateEmpId(emp.getFirstName()); 19 | System.out.println("The employee id: " + empId); 20 | 21 | SeniorityChecker seniorityChecker = new SeniorityChecker(); 22 | System.out.println("This employee is a " + 23 | seniorityChecker.checkSeniority(emp.getExperienceInYears()) + " employee."); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SRP/src/Employee.java: -------------------------------------------------------------------------------- 1 | class Employee { 2 | private String firstName; 3 | private String lastName; 4 | private double experienceInYears; 5 | 6 | public Employee(String firstName, String lastName, double experienceInYears) { 7 | this.firstName = firstName; 8 | this.lastName = lastName; 9 | this.experienceInYears = experienceInYears; 10 | } 11 | 12 | public String getFirstName() { 13 | return firstName; 14 | } 15 | 16 | public double getExperienceInYears() { 17 | return experienceInYears; 18 | } 19 | 20 | public void displayEmpDetail() { 21 | System.out.println("Employee: " + firstName + " " + lastName); 22 | System.out.println("Experience: " + experienceInYears + " years"); 23 | } 24 | } -------------------------------------------------------------------------------- /SRP/src/EmployeeIdGenerator.java: -------------------------------------------------------------------------------- 1 | class EmployeeIdGenerator { 2 | public String generateEmpId(String firstName) { 3 | return firstName.substring(0, 3).toUpperCase() + System.currentTimeMillis() % 1000; 4 | } 5 | } -------------------------------------------------------------------------------- /SRP/src/Main.java: -------------------------------------------------------------------------------- 1 | //TIP To Run code, press or 2 | // click the icon in the gutter. 3 | public class Main { 4 | public static void main(String[] args) { 5 | //TIP Press with your caret at the highlighted text 6 | // to see how IntelliJ IDEA suggests fixing it. 7 | System.out.printf("Hello and welcome!"); 8 | 9 | for (int i = 1; i <= 5; i++) { 10 | //TIP Press to start debugging your code. We have set one breakpoint 11 | // for you, but you can always add more by pressing . 12 | System.out.println("i = " + i); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /SRP/src/SeniorityChecker.java: -------------------------------------------------------------------------------- 1 | class SeniorityChecker { 2 | public String checkSeniority(double experienceInYears) { 3 | return experienceInYears > 5 ? "Senior" : "Junior"; 4 | } 5 | } -------------------------------------------------------------------------------- /Steps/FirstChapter.md: -------------------------------------------------------------------------------- 1 | فصل 1: مقدمه‌ای بر ساختمان داده‌ها 2 | • تعریف ساختمان داده 3 | • اهمیت ساختمان داده‌ها در مهندسی نرم‌افزار 4 | • ارتباط ساختمان داده با الگوریتم‌ها 5 | • پیچیدگی زمانی و فضایی (Big-O Notation) 6 | 7 | 1.1. تعریف ساختمان داده (Data Structure) 8 | ساختمان داده به مجموعه‌ای از روش‌ها و تکنیک‌ها گفته می‌شود که برای ذخیره، سازماندهی و دسترسی به داده‌ها در برنامه‌های نرم‌افزاری استفاده می‌شود. در واقع، ساختمان داده‌ها به ما این امکان را می‌دهند که داده‌ها را به‌صورت مؤثر و با کمترین هزینه در زمان و حافظه مدیریت کنیم. 9 | مثال: 10 | تصور کنید یک بانک اطلاعاتی از مشتریان دارید. شما نیاز دارید داده‌های مشتریان را ذخیره کنید، جستجو انجام دهید، و آنها را به‌روزرسانی کنید. اگر از یک ساختمان داده مناسب استفاده نکنید، این عملیات می‌تواند به‌طور چشمگیری کند شود. برای این کار، ممکن است از یک آرایه یا لیست پیوندی استفاده کنید که دسترسی به داده‌ها را سریعتر و کارآمدتر می‌کند. 11 | 12 | 1.1. تعریف ساختمان داده (Data 13 | 14 | Structure) - گسترش‌یافته 15 | ساختمان داده به‌طور کلی به روشی گفته می‌شود که داده‌ها در حافظه کامپیوتر ذخیره و سازماندهی می‌شوند. این مفهوم بسیار فراتر از صرفاً ذخیره داده‌ها است؛ ساختمان داده به ما کمک می‌کند که داده‌ها را به‌گونه‌ای سازمان‌دهی کنیم که انجام عملیات مختلف روی آنها مانند جستجو، افزودن، حذف، یا به‌روزرسانی، به‌طور کارآمدی انجام شود. انتخاب ساختمان داده مناسب برای حل یک مسئله خاص می‌تواند تأثیر بزرگی بر کارایی نرم‌افزار و عملکرد آن بگذارد. 16 | 17 | ویژگی‌های اساسی ساختمان داده: 18 | • ساختار: ساختمان داده، به ساختار کلی داده‌ها اشاره دارد که شامل روش‌هایی برای ارتباط داده‌ها با یکدیگر است. به‌عنوان مثال، درخت‌ها داده‌ها را به‌صورت سلسله‌مراتبی سازماندهی می‌کنند، در حالی که جداول هش داده‌ها را به‌صورت جفت کلید-مقدار ذخیره می‌کنند. 19 | • عملیات: عملیات‌هایی که می‌توانیم روی ساختمان داده انجام دهیم شامل اضافه کردن، حذف کردن، جستجو کردن، به‌روزرسانی کردن و مرتب کردن داده‌ها است. این عملیات‌ها باید به‌گونه‌ای طراحی شوند که کارآیی و بهینه بودن سیستم تضمین شود. 20 | • کاربرد: هدف اصلی استفاده از ساختمان داده‌ها، دسترسی سریع و کارآمد به داده‌ها است. برای مثال، در 21 | 22 | یک پایگاه داده، نیاز به جستجو در میان حجم وسیعی از اطلاعات داریم. اگر داده‌ها به‌طور مناسب سازماندهی نشده باشند، جستجو ممکن است کند و ناکارآمد باشد. 23 | 24 | مثال‌های ساده: 25 | • آرایه‌ها: آرایه‌ها ساده‌ترین نوع ساختمان داده هستند. یک آرایه به مجموعه‌ای از داده‌های هم‌نوع گفته می‌شود که در حافظه به‌طور پیوسته قرار می‌گیرند. این داده‌ها از طریق یک اندیس (index) قابل دسترسی هستند. 26 | مثال در زبان جاوا: 27 | در این مثال، آرایه arr پنج عدد صحیح را ذخیره می‌کند و شما می‌توانید هر یک از این اعداد را با استفاده از اندیس مشخص دسترسی پیدا کنید. پیچیدگی زمانی برای دسترسی به هر عنصر در آرایه O(1) است. 28 | • لیست پیوندی: لیست پیوندی نوعی ساختمان داده است که در آن هر عنصر (یا گره) به عنصر بعدی خود اشاره می‌کند. برخلاف آرایه‌ها که داده‌ها را به‌طور پیوسته ذخیره می‌کنند، در لیست پیوندی هر گره می‌تواند در هر کجای حافظه قرار داشته باشد و فقط با استفاده از ارجاع به گره بعدی به آن دسترسی پیدا می‌شود. 29 | مثال در زبان جاوا: مثال ۱.۱ 30 | 31 | 32 | در این مثال، لیست پیوندی با استفاده از گره‌ها پیاده‌سازی شده است. گره‌ها به‌صورت داینامیک ایجاد می‌شوند و در حافظه به‌طور غیرپیوسته ذخیره می‌شوند. پیچیدگی زمانی برای جستجو در لیست پیوندی O(n) است. 33 | 34 | تفاوت بین ساختمان داده و الگوریتم: 35 | ساختمان داده و الگوریتم‌ها دو جنبه مختلف از حل مشکلات کامپیوتری هستند، اما ارتباط نزدیکی با هم دارند. در واقع، ساختمان داده به‌عنوان ابزار یا "لوازم‌جانبی" برای الگوریتم‌ها عمل می‌کند. 36 | • ساختمان داده ابزارهایی برای ذخیره و سازمان‌دهی داده‌ها فراهم می‌آورد. 37 | • الگوریتم مجموعه‌ای از دستورالعمل‌ها است که برای انجام عملیات خاص روی داده‌ها از ساختمان داده‌ها استفاده می‌کند. 38 | مثالی از ارتباط ساختمان داده‌ها و الگوریتم‌ها: 39 | فرض کنید یک الگوریتم جستجو داریم که می‌خواهد یک عنصر خاص را در میان داده‌ها پیدا کند. اگر داده‌ها در یک آرایه مرتب‌شده ذخیره شده باشند، می‌توان از جستجوی باینری استفاده کرد که پیچیدگی زمانی آن O(log n) است. اما اگر داده‌ها به‌صورت لیست پیوندی ذخیره شوند، مجبور خواهیم بود از جستجوی خطی استفاده کنیم که پیچیدگی 40 | 41 | زمانی آن O(n) است. در اینجا انتخاب ساختمان داده (آرایه مرتب‌شده یا لیست پیوندی) تأثیر مستقیمی بر کارایی الگوریتم جستجو دارد. 42 | 43 | چرا انتخاب ساختمان داده اهمیت دارد؟ 44 | انتخاب مناسب ساختمان داده می‌تواند زمان اجرای برنامه‌ها را به‌طور چشمگیری کاهش دهد و منابع سیستم را بهینه کند. در واقع، بسیاری از مشکلات نرم‌افزاری پیچیده‌ای که در مقیاس‌های بزرگتر به‌وجود می‌آید، می‌توانند با انتخاب صحیح ساختمان داده حل شوند. 45 | • اگر یک سیستم نیاز به انجام عملیات سریع بر روی داده‌ها دارد، استفاده از یک جدول هش ممکن است بهترین گزینه باشد. 46 | • اگر نیاز به جستجو و مرتب‌سازی داده‌ها در یک درخت با ساختار خاص داریم، استفاده از درخت‌های جستجو (مثل AVL یا Red-Black Tree) مناسب‌تر است. 47 | مثال کاربردی دیگر: 48 | تصور کنید که یک سیستم سفارش آنلاین دارید. اگر بخواهید یک لیست از سفارشات ثبت‌شده را به‌صورت مرتب شده براساس تاریخ نمایش دهید، انتخاب یک درخت دودویی جستجو می‌تواند به شما کمک کند که جستجو، افزودن و حذف سفارشات را به‌طور سریع‌تری انجام دهید، در حالی که اگر از یک آرایه مرتب‌شده استفاده کنید، عملیات حذف یا 49 | 50 | افزودن می‌تواند زمان‌بر باشد. 51 | 52 | نتیجه‌گیری: 53 | تعریف ساختمان داده، علاوه بر آنکه مربوط به شیوه ذخیره و سازمان‌دهی داده‌ها است، با کارایی سیستم و عملکرد الگوریتم‌ها نیز ارتباط مستقیم دارد. برای هر مشکل نرم‌افزاری، انتخاب صحیح ساختمان داده می‌تواند تفاوت زیادی در کارایی ایجاد کند. درک صحیح و عمیق ساختمان داده‌ها به شما این امکان را می‌دهد که برنامه‌های بهینه‌تر و مقیاس‌پذیرتری طراحی کنید. 54 | 55 | 56 | 1.2. اهمیت ساختمان داده‌ها 57 | در مهندسی نرم‌افزار، طراحی ساختمان داده‌ها تأثیر مستقیمی بر عملکرد سیستم دارد. استفاده از یک ساختمان داده مناسب می‌تواند زمان اجرای برنامه را به‌طور چشمگیری کاهش دهد و همچنین هزینه‌های حافظه را بهینه کند. 58 | مثال: 59 | اگر از یک پشته برای انجام عملیات معکوس کردن یک عبارت استفاده کنید، عملیات به‌طور سریع‌تر و کارآمدتری انجام می‌شود تا زمانی که بخواهید از یک آرایه برای این کار استفاده کنید. 60 | 61 | 1.2. اهمیت ساختمان داده‌ها 62 | ساختمان داده‌ها در مهندسی نرم‌افزار به عنوان یکی از ارکان اصلی برای طراحی سیستم‌های کارآمد و مقیاس‌پذیر شناخته می‌شوند. استفاده از ساختمان داده مناسب تأثیر زیادی بر عملکرد سیستم دارد و می‌تواند موجب بهینه‌سازی در زمان، حافظه و مصرف منابع شود. درک اهمیت ساختمان داده‌ها برای هر توسعه‌دهنده و مهندس نرم‌افزار ضروری است، چراکه انتخاب صحیح می‌تواند در بهبود کارایی و مقیاس‌پذیری سیستم‌ها نقش کلیدی ایفا کند. 63 | 64 | 1.2.1. تأثیر بر زمان اجرا (Performance) 65 | یکی از بزرگ‌ترین اثرات انتخاب ساختمان داده مناسب، تأثیر آن بر زمان اجرا یا عملکرد سیستم است. بسیاری از مشکلات نرم‌افزاری از طریق انتخاب بهینه ساختمان داده قابل حل هستند، به‌ویژه در برنامه‌هایی که حجم زیادی از داده‌ها را پردازش می‌کنند. 66 | • جستجو: اگر داده‌ها در یک آرایه مرتب‌شده ذخیره شوند، عملیات جستجوی باینری با پیچیدگی زمانی O(log n) انجام می‌شود، اما اگر داده‌ها در یک لیست پیوندی ذخیره شوند، باید از جستجوی خطی استفاده کرد که پیچیدگی زمانی آن O(n) است. 67 | • اضافه کردن و حذف: در برخی ساختمان داده‌ها، مانند آرایه‌ها، عملیات افزودن یا حذف داده‌ها (خصوصاً در 68 | 69 | انتهای آرایه) سریع است، اما در دیگر ساختمان داده‌ها، مانند لیست‌های پیوندی، عملیات حذف یا افزودن در هر نقطه می‌تواند به سرعت انجام شود. 70 | 71 | 1.2.2. تأثیر بر استفاده از حافظه (Memory Usage) 72 | انتخاب ساختمان داده نه‌تنها تأثیر مستقیمی بر زمان اجرا دارد بلکه بر مصرف حافظه نیز تأثیر می‌گذارد. بسته به اینکه از چه نوع ساختاری برای ذخیره داده‌ها استفاده می‌کنید، ممکن است حافظه زیادی مورد نیاز باشد یا مصرف حافظه به حداقل برسد. 73 | • در آرایه‌ها، فضای حافظه به‌طور پیوسته تخصیص داده می‌شود و در صورتی که اندازه آرایه ثابت باشد، حافظه بهینه استفاده می‌شود. اما اگر اندازه آرایه به‌طور داینامیک تغییر کند، فضای بیشتری برای تغییر اندازه و جابجایی داده‌ها نیاز است. 74 | • در لیست‌های پیوندی، حافظه به‌طور غیر پیوسته تخصیص داده می‌شود. در این ساختار، هر گره علاوه بر داده، به یک اشاره‌گر برای گره بعدی نیاز دارد. این موضوع ممکن است باعث افزایش مصرف حافظه نسبت به آرایه‌ها شود. 75 | 76 | 1.2.3. تأثیر بر مقیاس‌پذیری سیستم 77 | 78 | (Scalability) 79 | سیستم‌هایی که داده‌های زیادی را پردازش می‌کنند باید قادر به مقیاس‌پذیری باشند. ساختمان داده‌ها تأثیر مستقیمی بر این موضوع دارند. به عنوان مثال، در سیستم‌هایی که نیاز به جستجو و به‌روزرسانی سریع داده‌ها دارند، استفاده از درخت‌های جستجوی متوازن مانند درخت AVL می‌تواند کارایی را به میزان قابل توجهی بهبود بخشد. این درخت‌ها قادر به انجام جستجو، حذف و افزودن داده‌ها در O(log n) زمان هستند. 80 | در مقابل، اگر از یک آرایه مرتب‌شده استفاده شود، انجام عملیات افزودن یا حذف می‌تواند به زمان خطی برسد که در مقیاس بزرگ مشکل‌ساز می‌شود. 81 | 82 | 1.2.4. تأثیر بر طراحی سیستم‌های توزیع‌شده 83 | در سیستم‌های توزیع‌شده که داده‌ها در چندین گره یا سرور ذخیره می‌شوند، انتخاب ساختمان داده‌ها می‌تواند پیچیدگی‌ها و چالش‌های زیادی ایجاد کند. در این سیستم‌ها، ساختمان داده‌هایی که به‌طور مؤثر بتوانند داده‌ها را در فضای توزیع‌شده ذخیره و بازیابی کنند، از اهمیت ویژه‌ای برخوردارند. 84 | برای مثال، جدول‌های هش توزیع‌شده می‌توانند کلیدهای جستجو را به‌طور کارآمد در سراسر سیستم توزیع‌شده تقسیم کنند. درخت‌های B+ که معمولاً در پایگاه‌داده‌ها استفاده می‌شوند، برای ذخیره‌سازی داده‌ها در دیسک طراحی شده‌اند 85 | 86 | و قابلیت جستجو و به‌روزرسانی سریع را فراهم می‌کنند. 87 | 88 | 1.2.5. تأثیر بر امنیت سیستم 89 | ساختمان داده‌ها همچنین در زمینه امنیت سیستم‌ها نقش دارند. به‌عنوان مثال، اگر بخواهیم از داده‌ها به‌طور امن محافظت کنیم، انتخاب ساختمان داده مناسب می‌تواند به افزایش امنیت کمک کند. یکی از مثال‌های معمول استفاده از درخت‌های B است که در بانک‌های اطلاعاتی برای ذخیره‌سازی داده‌های حساس استفاده می‌شود. 90 | • جداول هش می‌توانند برای ذخیره‌سازی پسوردها به کار روند. در این حالت، جداول هش به‌گونه‌ای طراحی می‌شوند که مقدار هش شده‌ی پسورد ذخیره شود و به‌این‌ترتیب پسورد اصلی هرگز در حافظه ذخیره نمی‌شود. 91 | • درخت‌های Merkle در بلاک‌چین‌ها برای تأمین یکپارچگی داده‌ها و بررسی صحت اطلاعات استفاده می‌شوند. این درخت‌ها به‌طور مؤثر اطلاعات را با یک ساختار درختی به هم متصل می‌کنند و صحت داده‌ها را بدون نیاز به بازبینی کامل آن‌ها تأمین می‌کنند. 92 | 93 | 1.2.6. تأثیر بر قابلیت نگهداری و توسعه سیستم‌ها 94 | در هر پروژه نرم‌افزاری، انتخاب ساختمان داده مناسب می‌تواند بر نگهداری و توسعه سیستم تأثیر بگذارد. انتخاب 95 | 96 | ساختمان داده‌ای که بتوان به‌راحتی آن را به‌روز کرد، تست کرد و گسترش داد، در طول عمر نرم‌افزار مفید خواهد بود. 97 | • به‌عنوان مثال، اگر بخواهیم یک سیستم مدیریت موجودی برای یک فروشگاه آنلاین طراحی کنیم، انتخاب یک ساختمان داده مانند درخت جستجو یا پشته می‌تواند به تیم توسعه کمک کند تا به‌راحتی محصولات را بر اساس ویژگی‌های خاص جستجو کنند. 98 | • همچنین، استفاده از ساختمان داده‌هایی که قابلیت تغییر سریع داشته باشند (مثل لیست‌های پیوندی) می‌تواند در مواقع نیاز به گسترش یا تغییر سیستم کمک کند. 99 | 100 | 1.2.7. مثال‌های کاربردی از اهمیت ساختمان داده‌ها 101 | • موتور جستجو: در موتورهای جستجو مثل گوگل، داده‌ها به‌طور پیچیده‌ای ذخیره می‌شوند تا امکان جستجوی سریع و بهینه فراهم شود. در این سیستم‌ها از ساختمان داده‌های خاصی مانند درخت‌های trie برای جستجو و گراف‌ها برای ارتباطات استفاده می‌شود. 102 | • پایگاه داده‌ها: در پایگاه داده‌های رابطه‌ای، جداول و شاخص‌ها به‌عنوان ساختمان داده استفاده می‌شوند تا عملیات جستجو و ذخیره‌سازی داده‌ها سریع و کارآمد باشد. 103 | • سیستم‌های توصیه‌گر: در سیستم‌های توصیه‌گر که اطلاعات مربوط به کاربران و محصولات را پردازش 104 | 105 | می‌کنند، انتخاب ساختمان داده‌های مناسب برای ذخیره‌سازی و جستجوی سریع، می‌تواند دقت و کارایی سیستم را به‌طور قابل توجهی افزایش دهد. 106 | 107 | نتیجه‌گیری 108 | ساختمان داده‌ها نه تنها تأثیر زیادی بر کارایی سیستم دارند، بلکه در تصمیم‌گیری‌های طراحی و توسعه نرم‌افزارها نقش بسیار مهمی ایفا می‌کنند. انتخاب صحیح ساختمان داده، می‌تواند به بهینه‌سازی مصرف منابع، افزایش سرعت و مقیاس‌پذیری سیستم و حتی تأمین امنیت داده‌ها کمک کند. درک عمیق و کاربردی این مفاهیم از ارکان اصلی هر مهندس نرم‌افزار است. 109 | 110 | 111 | 112 | 1.3. ارتباط ساختمان داده‌ها با الگوریتم‌ها 113 | هر الگوریتم نیاز به ساختمان داده‌ای دارد تا بتواند به‌طور بهینه کار کند. ساختمان داده‌ها و الگوریتم‌ها دو بخش جدا نشدنی از یکدیگرند. انتخاب مناسب یک ساختمان داده می‌تواند الگوریتم را بهینه کرده و در نتیجه عملکرد سیستم را بهبود بخشد. 114 | مثال: 115 | فرض کنید الگوریتم جستجوی خطی (Linear Search) را 116 | 117 | داریم. اگر داده‌ها در یک آرایه ذخیره شوند، این الگوریتم به‌صورت خطی (O(n)) عمل می‌کند. اما اگر داده‌ها در یک جدول هش (Hash Table) ذخیره شده باشند، جستجو می‌تواند با پیچیدگی زمانی O(1) انجام شود. 118 | 119 | 1.3. ارتباط ساختمان داده‌ها با الگوریتم‌ها 120 | ساختمان داده‌ها و الگوریتم‌ها دو مؤلفه اساسی و مکمل در طراحی نرم‌افزارهای کارآمد و مقیاس‌پذیر هستند. در واقع، ساختمان داده به‌عنوان یک ابزار برای ذخیره‌سازی و سازمان‌دهی داده‌ها عمل می‌کند، در حالی که الگوریتم‌ها مجموعه‌ای از دستورالعمل‌ها هستند که داده‌ها را پردازش می‌کنند. انتخاب مناسب ساختمان داده‌ها تأثیر مستقیمی بر پیچیدگی زمانی و فضایی الگوریتم‌ها خواهد داشت، و این ارتباط به‌طور مستقیم بر عملکرد سیستم‌ها تأثیر می‌گذارد. 121 | 122 | 1.3.1. نقش ساختمان داده‌ها در بهینه‌سازی الگوریتم‌ها 123 | هر الگوریتم برای انجام وظیفه‌ای خاص به داده‌ها نیاز دارد، و نحوه ذخیره‌سازی این داده‌ها می‌تواند سرعت و کارایی الگوریتم را تحت تأثیر قرار دهد. انتخاب ساختمان داده مناسب به الگوریتم‌ها این امکان را می‌دهد که عملیات مختلف را به‌طور کارآمدتر انجام دهند. در بسیاری از مواقع، عملکرد یک الگوریتم مستقیماً به نوع ساختمان داده‌ای که برای 124 | 125 | ذخیره‌سازی داده‌ها استفاده می‌شود، بستگی دارد. 126 | برای مثال، الگوریتم‌های جستجو به نوع ساختمان داده‌ای که برای ذخیره داده‌ها استفاده می‌شود، بسیار وابسته‌اند. به همین دلیل، شناخت ساختمان داده‌ها به طراحان الگوریتم‌ها این امکان را می‌دهد که الگوریتم‌های خود را بهینه کنند. 127 | 128 | 1.3.2. مثال‌های مهم از ارتباط ساختمان داده‌ها و الگوریتم‌ها 129 | 1.3.2.1. جستجوی باینری و آرایه‌ها 130 | یکی از مشهورترین و پرکاربردترین الگوریتم‌های جستجو، جستجوی باینری (Binary Search) است که تنها زمانی کارآمد است که داده‌ها به‌صورت مرتب در یک ساختمان داده ذخیره شده باشند، مانند آرایه مرتب‌شده. این الگوریتم با استفاده از تکنیک تقسیم و غلبه (Divide and Conquer) داده‌ها را در هر گام به دو قسمت تقسیم می‌کند و جستجو را به بخش کوچک‌تر ادامه می‌دهد، که پیچیدگی زمانی آن O(log n) است. 131 | در حالی که در یک آرایه مرتب‌شده پیچیدگی جستجو بهبود می‌یابد، اگر داده‌ها در یک لیست پیوندی ذخیره شوند، برای یافتن عنصر مورد نظر باید از جستجوی خطی استفاده کنیم، که پیچیدگی آن O(n) است. این نشان می‌دهد که انتخاب ساختمان داده مناسب برای جستجو می‌تواند تأثیر بسزایی در عملکرد الگوریتم داشته باشد. 132 | 133 | 134 | 1.3.2.2. مرتب‌سازی و آرایه‌ها یا لیست‌ها 135 | الگوریتم‌های مرتب‌سازی یکی از مهم‌ترین دسته‌های الگوریتم‌ها هستند که داده‌ها را بر اساس یک ترتیب خاص مرتب می‌کنند. الگوریتم‌هایی مانند مرتب‌سازی سریع (Quick Sort) یا مرتب‌سازی ادغامی (Merge Sort) برای کارایی بیشتر به ساختمان داده‌های خاص نیاز دارند. 136 | • در مرتب‌سازی سریع (Quick Sort)، انتخاب یک پشته برای نگهداری بخش‌های تقسیم‌شده داده‌ها می‌تواند به بهبود کارایی کمک کند. 137 | • در مرتب‌سازی ادغامی (Merge Sort)، استفاده از یک آرایه یا لیست پیوندی برای ذخیره داده‌ها اهمیت زیادی دارد. در این الگوریتم، داده‌ها به‌طور مکرر تقسیم و سپس ادغام می‌شوند، که این فرایند در لیست‌های پیوندی می‌تواند پیچیدگی بیشتری به همراه داشته باشد زیرا نیاز به کپی کردن و جابجایی عناصر است. 138 | 139 | 1.3.3. تأثیر انتخاب ساختمان داده بر پیچیدگی زمانی الگوریتم‌ها 140 | انتخاب ساختمان داده مناسب می‌تواند پیچیدگی زمانی الگوریتم‌ها را کاهش دهد یا آن را افزایش دهد. به‌طور کلی، هر ساختمان داده‌ای ویژگی‌های خاص خود را دارد که باعث می‌شود برخی عملیات‌ها بر روی آن کارآمدتر از دیگر عملیات 141 | 142 | باشند. این ویژگی‌ها بر انتخاب الگوریتم مناسب تأثیر می‌گذارند. 143 | 144 | 1.3.3.1. آرایه‌ها 145 | آرایه‌ها ساختارهای داده‌ای هستند که در آن‌ها داده‌ها به‌طور پیوسته در حافظه ذخیره می‌شوند و به‌وسیله اندیس قابل دسترسی هستند. این ویژگی باعث می‌شود که عملیات‌هایی مثل دسترسی تصادفی (Random Access) به داده‌ها با پیچیدگی O(1) انجام شود. اما اضافه کردن یا حذف داده‌ها از میانه آرایه پیچیدگی زمانی O(n) دارد، زیرا باید عناصر جابجا شوند. 146 | • الگوریتم جستجوی خطی (Linear Search) بر روی آرایه‌ها به‌طور خطی عمل می‌کند، که پیچیدگی زمانی آن O(n) است. 147 | 148 | 1.3.3.2. لیست‌های پیوندی 149 | لیست‌های پیوندی در مقایسه با آرایه‌ها به‌طور غیر پیوسته در حافظه ذخیره می‌شوند و دسترسی به داده‌ها از طریق ارجاع به گره‌های مختلف انجام می‌شود. این ساختار برای عملیات‌هایی مثل اضافه کردن و حذف داده‌ها سریع است (در O(1) زمان در صورت دسترسی به گره مورد نظر). اما عملیات دسترسی تصادفی به داده‌ها در لیست پیوندی به‌طور خطی انجام می‌شود و پیچیدگی زمانی آن O(n) است. 150 | 151 | • الگوریتم جستجوی خطی به‌خوبی روی لیست‌های پیوندی پیاده‌سازی می‌شود، اما به دلیل عدم دسترسی تصادفی به داده‌ها، جستجو ممکن است زمان بیشتری ببرد. 152 | 153 | 1.3.3.3. درخت‌ها 154 | درخت‌ها به‌ویژه درخت‌های جستجوی دودویی (Binary Search Trees) به الگوریتم‌ها این امکان را می‌دهند که عملیات‌هایی مانند جستجو، افزودن و حذف داده‌ها را در O(log n) زمان انجام دهند، که این ویژگی می‌تواند به‌طور قابل توجهی عملکرد الگوریتم‌ها را بهبود بخشد. 155 | • الگوریتم جستجوی دودویی (Binary Search) زمانی که داده‌ها در یک درخت جستجوی دودویی متوازن ذخیره می‌شوند، می‌تواند جستجوی کارآمدی ارائه دهد. 156 | 157 | 1.3.4. انتخاب ساختمان داده مناسب برای الگوریتم‌ها 158 | انتخاب ساختمان داده مناسب برای یک الگوریتم نیاز به تحلیل دقیق ویژگی‌ها و نیازمندی‌های سیستم دارد. در برخی از مواقع، نیاز است که بین کارایی زمانی و مصرف حافظه تعادل برقرار شود. 159 | • جداول هش برای جستجوی سریع جفت‌های کلید-مقدار کاربرد دارند و عملیات‌هایی مثل اضافه کردن و حذف 160 | 161 | داده‌ها را در O(1) زمان انجام می‌دهند. 162 | • در صورتی که نیاز به ترتیب‌دهی داده‌ها وجود داشته باشد، درخت‌های دودویی جستجو (BST) یا درخت‌های متوازن مانند درخت‌های AVL یا درخت‌های Red-Black انتخاب بهتری خواهند بود. 163 | 164 | 1.3.5. تعامل دوطرفه ساختمان داده‌ها و الگوریتم‌ها 165 | رابطه بین ساختمان داده‌ها و الگوریتم‌ها بیشتر یک تعامل دوطرفه است. الگوریتم‌ها به ساختمان داده‌ها نیاز دارند تا داده‌ها را پردازش کنند، و در عین حال، انتخاب صحیح ساختمان داده به طراحی کارآمدتر الگوریتم‌ها کمک می‌کند. 166 | • در یک سیستم پایگاه داده، انتخاب یک درخت B+ برای ذخیره‌سازی داده‌ها باعث می‌شود که عملیات جستجو، افزودن و حذف در مقیاس بزرگ به‌طور کارآمدتری انجام شود. 167 | • در سیستم‌های فایل، انتخاب یک درخت پرونده (File Tree) یا درخت پوشه برای ذخیره‌سازی داده‌ها موجب تسهیل در دسترسی و مدیریت فایل‌ها می‌شود. 168 | 169 | نتیجه‌گیری 170 | ساختمان داده‌ها و الگوریتم‌ها همواره به‌طور متقابل با یکدیگر در ارتباط هستند. انتخاب ساختمان داده مناسب می‌تواند 171 | 172 | باعث بهبود عملکرد و کارایی الگوریتم‌ها شود. درک درست این ارتباط برای طراحی سیستم‌های نرم‌افزاری مؤثر و مقیاس‌پذیر حیاتی است. هر زمان که با یک مشکل جدید روبرو می‌شویم، انتخاب درست ساختمان داده نه تنها پیچیدگی زمانی الگوریتم‌ها را کاهش می‌دهد، بلکه در مصرف منابع سیستم نیز تأثیر زیادی خواهد داشت. 173 | 174 | 175 | 1.4. پیچیدگی زمانی و فضایی (Big-O Notation) 176 | در طراحی ساختمان داده‌ها، یکی از مفاهیم مهم که باید در نظر گرفت، پیچیدگی زمانی و فضایی است. این مفهوم به ما کمک می‌کند تا ارزیابی کنیم که یک ساختمان داده چقدر کارآمد است و چه مقدار منابع (زمان و حافظه) مصرف می‌کند. 177 | 1.4.1. پیچیدگی زمانی (Time Complexity) 178 | پیچیدگی زمانی نشان می‌دهد که یک عملیات خاص روی یک ساختمان داده چقدر زمان می‌برد. معمولاً این پیچیدگی با نماد O نمایش داده می‌شود. 179 | • O(1): عملیات ثابت (constant time) – این یعنی زمان اجرای عملیات مستقل از اندازه داده‌ها است. 180 | • O(n): عملیات خطی (linear time) – این یعنی زمان اجرای عملیات به اندازه داده‌ها بستگی دارد. 181 | • O(log n): عملیات لگاریتمی (logarithmic time) – 182 | 183 | این معمولاً در جستجوهای دودویی یا درخت‌های جستجو مشاهده می‌شود. 184 | مثال: 185 | • در یک آرایه، دسترسی به هر عنصر با اندیس مشخصی O(1) است. 186 | • در یک لیست پیوندی، برای دسترسی به یک عنصر خاص باید از ابتدا شروع کرده و به ترتیب به آن برسید، که زمان آن O(n) است. 187 | 188 | 1.4. انواع مختلف ساختمان داده‌ها 189 | ساختمان داده‌ها به ساختارهایی گفته می‌شود که داده‌ها را به‌طور منظم و با روش‌های خاصی ذخیره می‌کنند تا عملیات مختلف بر روی آن‌ها به‌طور مؤثر و کارآمد انجام شود. انتخاب نوع مناسب ساختمان داده می‌تواند تأثیر زیادی بر کارایی و عملکرد الگوریتم‌ها داشته باشد. در این قسمت، به بررسی انواع مختلف ساختمان داده‌ها و ویژگی‌ها، کاربردها و معایب هر یک خواهیم پرداخت. 190 | 191 | 1.4.1. آرایه‌ها (Arrays) 192 | آرایه‌ها ساختار داده‌ای خطی هستند که در آن‌ها داده‌ها به‌طور پیوسته در حافظه ذخیره می‌شوند و از طریق ایندکس به آن‌ها دسترسی پیدا می‌شود. آرایه‌ها یکی از ساده‌ترین و پرکاربردترین ساختمان داده‌ها هستند و برای ذخیره 193 | 194 | مجموعه‌ای از داده‌ها با اندازه ثابت یا متغیر بسیار مناسب‌اند. 195 | • ویژگی‌ها: 196 | • دسترسی تصادفی به عناصر (عملیات دسترسی در O(1) زمان). 197 | • افزودن یا حذف عناصر در وسط آرایه نیازمند جابجایی داده‌ها است که پیچیدگی آن O(n) است. 198 | • حافظه به‌صورت پیوسته تخصیص داده می‌شود. 199 | • کاربردها: 200 | • زمانی که به دسترسی سریع به داده‌ها با ایندکس ثابت نیاز داریم، مانند ذخیره مجموعه‌ای از مقادیر عددی. 201 | • الگوریتم‌های مرتب‌سازی و جستجو، مانند مرتب‌سازی سریع (Quick Sort). 202 | • ذخیره داده‌ها به‌صورت ثابت، مانند ماتریس‌ها و جدول‌های پراکندگی. 203 | • معایب: 204 | • تغییر اندازه آرایه‌ها مشکل‌ساز است و در صورت نیاز به اضافه کردن داده‌های جدید یا تغییر اندازه، ممکن است زمان زیادی صرف شود. 205 | • افزودن و حذف داده‌ها به‌طور تصادفی یا در وسط آرایه پیچیده و پرهزینه است. 206 | 207 | 1.4.2. لیست‌های پیوندی (Linked Lists) 208 | لیست‌های پیوندی یک نوع ساختمان داده‌ای غیر پیوسته 209 | 210 | هستند که در آن‌ها داده‌ها به‌صورت گره‌هایی ذخیره می‌شوند که هر گره شامل داده و اشاره‌گری به گره بعدی است. لیست‌های پیوندی نسبت به آرایه‌ها از انعطاف‌پذیری بیشتری برخوردارند و می‌توانند به راحتی تغییر اندازه دهند. 211 | • ویژگی‌ها: 212 | • دسترسی به داده‌ها به‌صورت خطی انجام می‌شود و پیچیدگی دسترسی به عنصر خاص در O(n) است. 213 | • افزودن یا حذف گره‌ها در ابتدا یا انتهای لیست در O(1) زمان انجام می‌شود. 214 | • حافظه به‌صورت غیر پیوسته تخصیص داده می‌شود. 215 | • کاربردها: 216 | • زمانی که به تغییرات مکرر در داده‌ها نیاز داریم، مانند فهرست‌های داینامیک یا صف‌ها و پشته‌ها. 217 | • در الگوریتم‌های جستجو و مرتب‌سازی که به‌طور متوالی داده‌ها را پردازش می‌کنند. 218 | • معایب: 219 | • دسترسی تصادفی به داده‌ها در لیست پیوندی نیازمند پیمایش گره‌ها است که پیچیدگی O(n) دارد. 220 | • مصرف حافظه اضافی به دلیل نیاز به ذخیره اشاره‌گرها برای هر گره. 221 | 222 | 1.4.3. پشته‌ها (Stacks) 223 | پشته‌ها ساختار داده‌ای هستند که از الگوریتم LIFO (آخرین 224 | 225 | وارد، اولین خارج) پیروی می‌کنند. در پشته‌ها، تنها به آخرین داده وارد شده دسترسی داریم و عملیات افزودن و حذف داده‌ها فقط از بالای پشته انجام می‌شود. 226 | • ویژگی‌ها: 227 | • دسترسی به آخرین عنصر وارد شده تنها با استفاده از عملیات push (افزودن) و pop (حذف) ممکن است. 228 | • پیچیدگی زمانی برای عملیات‌ها در O(1) است. 229 | • کاربردها: 230 | • استفاده در پیاده‌سازی الگوریتم‌های بازگشتی. 231 | • در پردازش‌های مربوط به توازن پرانتزها و همچنین در ماشین‌های حالت. 232 | • در الگوریتم‌هایی مانند Depth First Search (DFS) برای پیمایش درخت‌ها و گراف‌ها. 233 | • معایب: 234 | • تنها به عنصر آخر دسترسی داریم و نمی‌توان به سایر عناصر پشته دسترسی داشت. 235 | • در صورت پر شدن پشته، ممکن است با خطا مواجه شویم (Overflow). 236 | 237 | 1.4.4. صف‌ها (Queues) 238 | صف‌ها ساختار داده‌ای هستند که از الگوریتم FIFO (اولین وارد، اولین خارج) پیروی می‌کنند. در صف‌ها، داده‌ها به ترتیب وارد شده و از آن‌ها به ترتیب حذف می‌شود. 239 | 240 | • ویژگی‌ها: 241 | • عملیات enqueue (افزودن) و dequeue (حذف) در O(1) زمان انجام می‌شود. 242 | • به‌طور کلی، صف‌ها می‌توانند ساده یا اولویت‌دار (Priority Queue) باشند. 243 | • کاربردها: 244 | • در پردازش داده‌های ترتیبی مانند پردازش درخواست‌ها در سیستم‌های سرور. 245 | • در الگوریتم‌های Breadth First Search (BFS) برای پیمایش گراف‌ها. 246 | • در پیاده‌سازی الگوریتم‌های صف‌بندی برای پردازش‌های همزمان. 247 | • معایب: 248 | • نمی‌توان به عناصر به‌طور تصادفی دسترسی داشت. 249 | • برای دسترسی به داده‌های خاص، باید تمام عناصر قبلی را از صف خارج کنیم. 250 | 251 | 1.4.5. درخت‌ها (Trees) 252 | درخت‌ها یک ساختار داده هیرارشی هستند که به‌طور طبیعی برای مدل‌سازی روابط سلسله‌مراتبی مناسب‌اند. هر گره در درخت ممکن است چندین گره فرزند داشته باشد و درخت‌ها به انواع مختلفی تقسیم می‌شوند، از جمله درخت‌های جستجوی دودویی (Binary Search Tree) و درخت‌های 253 | 254 | متوازن. 255 | • ویژگی‌ها: 256 | • پیچیدگی جستجو، افزودن و حذف در درخت‌های متوازن در O(log n) زمان است. 257 | • درخت‌ها می‌توانند متوازن یا نامتوازن باشند، و در درخت‌های نامتوازن، عملکرد ممکن است به بدترین حالت یعنی O(n) برسد. 258 | • کاربردها: 259 | • در پایگاه‌های داده برای ذخیره‌سازی داده‌ها به‌صورت مرتب و سریع. 260 | • الگوریتم‌هایی مانند Quick Sort و Merge Sort از درخت‌ها برای تقسیم و ادغام داده‌ها استفاده می‌کنند. 261 | • سیستم‌های فایل و پایگاه داده‌های NoSQL، که از درخت‌های B+ و مشابه آن استفاده می‌کنند. 262 | • معایب: 263 | • در صورت عدم متوازن بودن، پیچیدگی الگوریتم‌ها ممکن است به بدترین حالت برسد. 264 | • مصرف حافظه نسبت به ساختمان داده‌های ساده‌تر مانند آرایه‌ها بیشتر است. 265 | 266 | 1.4.6. جداول هش (Hash Tables) 267 | جداول هش ساختمان داده‌ای است که برای ذخیره‌سازی داده‌ها به‌صورت جفت‌های کلید-مقدار طراحی شده است. 268 | 269 | جداول هش از یک تابع هش برای تعیین محل ذخیره‌سازی داده‌ها استفاده می‌کنند. این ساختمان داده برای جستجوهای سریع و ذخیره‌سازی داده‌های کلید-مقدار بسیار مؤثر است. 270 | • ویژگی‌ها: 271 | • دسترسی به داده‌ها به‌طور معمول در O(1) زمان انجام می‌شود. 272 | • در صورتی که برخورد هش (Collisions) رخ دهد، باید از روش‌هایی مانند زنجیره‌سازی یا بازآرایی برای مدیریت آن‌ها استفاده کرد. 273 | • کاربردها: 274 | • در جستجوهای سریع برای داده‌های کلید-مقدار. 275 | • در پیاده‌سازی سیستم‌های کش (Cache) و ذخیره‌سازی داده‌ها در برنامه‌ها. 276 | • معایب: 277 | • در صورت وجود برخورد هش، پیچیدگی عملکرد ممکن است افزایش یابد. 278 | • انتخاب تابع هش مناسب برای جلوگیری از برخوردهای زیاد بسیار مهم است. 279 | 280 | 1.4.7. گراف‌ها (Graphs) (ادامه) 281 | • ویژگی‌ها: 282 | • گراف‌ها می‌توانند جهت‌دار یا بی‌جهت باشند. در گراف‌های جهت‌دار، یال‌ها دارای جهت هستند و در 283 | 284 | گراف‌های بی‌جهت، یال‌ها بدون جهت هستند. 285 | • گراف‌ها می‌توانند وزن‌دار یا بدون وزن باشند. در گراف‌های وزن‌دار، هر یال دارای یک وزن است که می‌تواند نشان‌دهنده هزینه یا فاصله باشد. 286 | • گراف‌ها می‌توانند متراکم یا پراکنده باشند. در گراف‌های متراکم تعداد یال‌ها نزدیک به بیشینه تعداد یال‌ها است و در گراف‌های پراکنده، تعداد یال‌ها کم است. 287 | • ساختار ذخیره‌سازی گراف می‌تواند به دو صورت ماتریس مجاورت (Adjacency Matrix) یا لیست مجاورت (Adjacency List) باشد: 288 | • ماتریس مجاورت یک آرایه دو بعدی است که در آن هر خانه ماتریس نشان‌دهنده وجود یا عدم وجود یال بین دو گره است. 289 | • لیست مجاورت از یک لیست استفاده می‌کند که در آن هر گره یک لیست از گره‌های مجاور خود دارد. 290 | • کاربردها: 291 | • در شبکه‌های اجتماعی، برای مدل‌سازی ارتباطات میان کاربران و روابط آن‌ها. 292 | • در شبکه‌های کامپیوتری، برای مدل‌سازی ارتباطات و مسیرهای انتقال داده بین سرورها. 293 | • در سیستم‌های حمل‌ونقل، برای مدل‌سازی مسیرهای موجود بین ایستگاه‌ها و محاسبه کوتاه‌ترین مسیر. 294 | • در الگوریتم‌های مسیریابی مانند Dijkstra و Bellman-Ford برای یافتن کوتاه‌ترین مسیر در گراف‌ها. 295 | 296 | • در الگوریتم‌های جستجو و پیمایش مانند BFS (Breadth-First Search) و DFS (Depth-First Search). 297 | • معایب: 298 | • گراف‌ها به‌ویژه در مواردی که تعداد گره‌ها و یال‌ها زیاد است، می‌توانند حافظه زیادی مصرف کنند. 299 | • پیچیدگی مدیریت گراف‌ها می‌تواند زیاد باشد، به خصوص در گراف‌های با وزن‌های مختلف یا گراف‌های جهت‌دار. 300 | 301 | 1.4.8. مجموعه‌ها و دیکشنری‌ها (Sets and Dictionaries) 302 | مجموعه‌ها (Sets) و دیکشنری‌ها (Dictionaries) ساختارهای داده‌ای هستند که به‌طور گسترده‌ای در برنامه‌نویسی برای ذخیره‌سازی داده‌های یکتا یا جفت‌های کلید-مقدار استفاده می‌شوند. 303 | • مجموعه‌ها (Sets): 304 | • مجموعه‌ها یک نوع ساختمان داده بدون ترتیب و یکتا هستند که برای نگهداری عناصر بدون تکرار استفاده می‌شوند. 305 | • عملیات‌هایی مانند افزودن، حذف، و جستجو در مجموعه‌ها معمولاً در O(1) زمان انجام می‌شود. 306 | • مجموعه‌ها معمولاً از جداول هش برای ذخیره‌سازی 307 | 308 | داده‌ها استفاده می‌کنند. 309 | • ویژگی‌ها: 310 | • حافظه به‌صورت غیر پیوسته تخصیص داده می‌شود. 311 | • عملیات جستجو، افزودن و حذف در O(1) زمان است. 312 | • از حذف یا افزودن عناصر تکراری جلوگیری می‌شود. 313 | • کاربردها: 314 | • در مواردی که به دنبال ذخیره داده‌های یکتا هستیم، مانند حذف مقادیر تکراری از یک مجموعه. 315 | • در الگوریتم‌هایی که نیاز به بررسی وجود یا عدم وجود یک عنصر دارند، مانند بررسی تعلق یک عنصر به مجموعه‌ای خاص. 316 | • معایب: 317 | • عدم ترتیب در ذخیره‌سازی داده‌ها می‌تواند در مواردی که ترتیب خاصی مورد نیاز است مشکل‌ساز باشد. 318 | • دیکشنری‌ها (Dictionaries): 319 | • دیکشنری‌ها یا Map یک ساختمان داده هستند که جفت‌های کلید-مقدار را ذخیره می‌کنند. در دیکشنری‌ها، هر کلید باید یکتا باشد و به آن مقدار خاصی متصل است. 320 | • برای پیاده‌سازی دیکشنری‌ها معمولاً از جداول هش استفاده می‌شود که عملیات جستجو، افزودن و حذف را در O(1) زمان انجام می‌دهند. 321 | • ویژگی‌ها: 322 | • دسترسی سریع به داده‌ها از طریق کلیدها. 323 | • معمولاً از جداول هش برای پیاده‌سازی استفاده می‌شود 324 | 325 | که باعث دسترسی سریع به داده‌ها می‌شود. 326 | • کاربردها: 327 | • در ذخیره‌سازی جفت‌های کلید-مقدار، مانند ذخیره‌سازی داده‌ها در پایگاه‌های داده، کش‌ها یا در پردازش‌های شبکه. 328 | • در پیاده‌سازی الگوریتم‌هایی مانند جستجوهای سریع یا نگهداری اطلاعات در فرمت‌های کلید-مقدار. 329 | • معایب: 330 | • نیاز به تابع هش مناسب برای جلوگیری از برخوردها. 331 | • ممکن است در صورت برخورد هش‌ها، کارایی دیکشنری کاهش یابد. 332 | 333 | 1.4.9. ساختار داده‌های ترکیبی (Composite Data Structures) 334 | ساختمان داده‌های ترکیبی به ساختمان داده‌هایی اطلاق می‌شود که از ترکیب چند ساختمان داده دیگر ساخته می‌شوند. این نوع ساختارها برای حل مشکلات پیچیده‌تر و انجام عملیات خاص بر روی داده‌ها طراحی شده‌اند. 335 | • ویژگی‌ها: 336 | • می‌توانند از ترکیب انواع مختلف ساختمان داده‌ها استفاده کنند، مانند ترکیب درخت‌ها، گراف‌ها، و جداول هش. 337 | • مناسب برای حل مسائل پیچیده و بهینه‌سازی عملکرد در شرایط خاص. 338 | 339 | • کاربردها: 340 | • در پیاده‌سازی ساختارهای پیچیده مانند Heaps، Trie، Disjoint Set Union (DSU) و Segment Tree. 341 | • در الگوریتم‌های MST (Minimum Spanning Tree) و الگوریتم‌های دینامیک برنامه‌نویسی. 342 | • معایب: 343 | • پیچیدگی بالای پیاده‌سازی و نیاز به درک دقیق ساختار داده‌ها. 344 | • مصرف حافظه زیاد به‌ویژه در مواردی که نیاز به ذخیره داده‌ها در چندین سطح مختلف است. 345 | 346 | جمع‌بندی 347 | در این قسمت، انواع مختلف ساختمان داده‌ها را مورد بررسی قرار دادیم. هر نوع ساختمان داده مزایا و معایب خاص خود را دارد که باید با توجه به نیازهای خاص هر الگوریتم یا مسئله انتخاب شود. درک صحیح و کاربردی از هر ساختمان داده می‌تواند به طراحان سیستم‌ها کمک کند تا بهترین عملکرد را از نظر سرعت و مصرف حافظه داشته باشند. برای انتخاب درست ساختمان داده، باید به عواملی مانند نوع داده‌ها، تعداد داده‌ها، عملیات مورد نیاز و پیچیدگی زمانی و فضایی هر عملیات توجه کرد. 348 | 349 | 350 | 1.5. انواع ساختمان داده‌ها 351 | در این بخش، چند نوع از ساختمان داده‌ها را که در فصل‌های بعدی به‌طور مفصل بررسی خواهیم کرد، معرفی می‌کنیم: 352 | • آرایه‌ها (Arrays): یک ساختار داده‌ای است که داده‌ها را در مکان‌های متوالی در حافظه ذخیره می‌کند. 353 | • مزایا: دسترسی سریع به داده‌ها با استفاده از اندیس. 354 | • معایب: تغییر اندازه آرایه مشکل‌ساز است. 355 | • لیست‌های پیوندی (Linked Lists): یک ساختار داده‌ای است که داده‌ها را به‌صورت گره‌هایی که به هم متصل هستند، ذخیره می‌کند. 356 | • مزایا: اضافه و حذف داده‌ها سریع است. 357 | • معایب: دسترسی تصادفی به داده‌ها غیرممکن است. 358 | • پشته‌ها (Stacks): یک ساختار داده‌ای است که به‌صورت LIFO (Last In, First Out) عمل می‌کند. 359 | • مزایا: استفاده از پشته‌ها در پیاده‌سازی ماشین‌های حالت‌گذار و بازگشتی (Recursion). 360 | • معایب: دسترسی به عناصر غیر از بالای پشته امکان‌پذیر نیست. 361 | • صف‌ها (Queues): یک ساختار داده‌ای است که به‌صورت FIFO (First In, First Out) عمل می‌کند. 362 | • مزایا: مناسب برای استفاده در سیستم‌های صف‌بندی و پردازش در زمان واقعی. 363 | 364 | • معایب: عملیات جستجو و دسترسی به داده‌های میانه به‌آسانی قابل انجام نیست. 365 | • درخت‌ها (Trees): مجموعه‌ای از گره‌ها که به‌صورت سلسله‌مراتبی با هم ارتباط دارند. 366 | • مزایا: مناسب برای جستجو، مرتب‌سازی و سازمان‌دهی داده‌ها. 367 | • معایب: پیچیدگی ساختار درختی ممکن است باعث کندی عملیات شود. 368 | 369 | 1.5. پیچیدگی زمانی و فضایی ساختمان داده‌ها 370 | در این بخش، به تحلیل پیچیدگی‌های زمانی و فضایی ساختمان داده‌ها خواهیم پرداخت. این مفاهیم برای درک بهتر عملکرد الگوریتم‌ها و ساختمان داده‌ها در دنیای واقعی ضروری هستند. پیچیدگی زمانی و فضایی به‌عنوان معیارهای اصلی برای سنجش کارایی الگوریتم‌ها و ساختمان داده‌ها استفاده می‌شود و تعیین می‌کنند که الگوریتم‌ها در برابر داده‌های بزرگ چگونه عمل خواهند کرد. 371 | 1.5.1. پیچیدگی زمانی (Time Complexity) 372 | پیچیدگی زمانی به میزان زمانی که یک الگوریتم برای حل یک مسئله نیاز دارد، اشاره دارد. این پیچیدگی معمولاً به تعداد عملیات‌های پایه‌ای که الگوریتم برای حل مشکل انجام می‌دهد، بستگی دارد و با استفاده از نماد اُ-بزرگتر (Big-O notation) 373 | 374 | نمایش داده می‌شود. این تحلیل به ما می‌گوید که چگونه زمان اجرای الگوریتم با افزایش ورودی‌ها تغییر می‌کند. 375 | برای تحلیل پیچیدگی زمانی یک ساختمان داده، به‌طور کلی عملیات‌هایی که روی آن انجام می‌شود، مانند جستجو، افزودن، حذف و دسترسی، را بررسی می‌کنیم. در این بخش، برخی از پیچیدگی‌های زمانی رایج برای انواع مختلف ساختمان داده‌ها آورده شده است: 376 | • آرایه‌ها: 377 | • دسترسی به عنصر: دسترسی به هر عنصر در آرایه با استفاده از ایندکس در O(1) زمان انجام می‌شود. 378 | • افزودن به انتهای آرایه: در صورتی که ظرفیت آرایه تمام نشده باشد، افزودن یک عنصر به انتهای آرایه در O(1) زمان است. اما اگر آرایه نیاز به افزایش اندازه داشته باشد، این عملیات در بدترین حالت می‌تواند O(n) باشد. 379 | • حذف یا افزودن به وسط آرایه: این عملیات در O(n) زمان انجام می‌شود، چون برای جابجایی عناصر پس از محل درج یا حذف، به زمان خطی نیاز داریم. 380 | • لیست‌های پیوندی: 381 | • دسترسی به عنصر: برای دسترسی به یک عنصر خاص باید از ابتدا یا انتهای لیست شروع کرده و به ترتیب گره‌ها را پیمایش کنیم. بنابراین پیچیدگی زمان دسترسی O(n) است. 382 | • افزودن یا حذف از ابتدا یا انتهای لیست: این عملیات‌ها در O(1) زمان انجام می‌شود، چون فقط نیاز به تغییر 383 | 384 | اشاره‌گرها داریم. 385 | • افزودن یا حذف از وسط لیست: این عملیات در O(n) زمان انجام می‌شود، چون باید گره مورد نظر را پیدا کنیم و سپس عملیات را انجام دهیم. 386 | • پشته‌ها و صف‌ها: 387 | • افزودن و حذف از پشته یا صف: این عملیات‌ها در هر دو ساختار در O(1) زمان انجام می‌شوند، چون فقط با بالای پشته یا انتهای صف سر و کار داریم. 388 | • دسترسی به عنصر خاص: در پشته‌ها و صف‌ها امکان دسترسی تصادفی به عنصر خاص وجود ندارد، بنابراین پیچیدگی دسترسی به یک عنصر خاص در این ساختارها O(n) است. 389 | • دیکشنری‌ها (جداول هش): 390 | • جستجو، افزودن و حذف: این عملیات‌ها معمولاً در O(1) زمان انجام می‌شوند، چون از جدول هش برای دسترسی سریع به داده‌ها استفاده می‌شود. 391 | • در صورت برخورد هش (Collisions): در صورتی که برخورد هش رخ دهد، پیچیدگی زمانی ممکن است به O(n) برسد. الگوریتم‌های مختلفی برای مدیریت برخوردها وجود دارد که می‌توانند پیچیدگی را کاهش دهند. 392 | • گراف‌ها: 393 | • جستجو و پیمایش (BFS و DFS): این عملیات‌ها بستگی به نوع نمایش گراف (ماتریس مجاورت یا لیست 394 | 395 | مجاورت) دارند. در گراف‌های با لیست مجاورت، پیچیدگی جستجو یا پیمایش O(V + E) است، که در آن V تعداد گره‌ها و E تعداد یال‌ها است. در گراف‌های با ماتریس مجاورت، پیچیدگی به O(V^2) می‌رسد. 396 | • افزودن و حذف یال‌ها یا گره‌ها: این عملیات‌ها بسته به نحوه ذخیره‌سازی گراف می‌توانند در O(1) یا O(V) زمان انجام شوند. 397 | 1.5.2. پیچیدگی فضایی (Space Complexity) 398 | پیچیدگی فضایی به میزان حافظه‌ای که یک الگوریتم برای ذخیره داده‌ها یا متغیرها به‌کار می‌برد، اشاره دارد. این پیچیدگی نیز معمولاً با استفاده از نماد اُ-بزرگتر (Big-O) نمایش داده می‌شود و به‌طور خاص به حجم حافظه مصرفی وابسته به اندازه ورودی و تعداد عملیات‌های داده شده است. 399 | برای ساختمان داده‌ها، پیچیدگی فضایی به‌ویژه به نحوه ذخیره‌سازی داده‌ها و نیازمندی‌های حافظه آن‌ها بستگی دارد. در اینجا به بررسی پیچیدگی فضایی چند ساختمان داده رایج می‌پردازیم: 400 | • آرایه‌ها: 401 | • حافظه مورد نیاز برای ذخیره‌سازی یک آرایه به تعداد عناصر آن بستگی دارد. بنابراین، پیچیدگی فضایی برای یک آرایه از O(n) است، که در آن n تعداد عناصر است. 402 | • اگر آرایه دینامیک باشد (مانند آرایه‌های در زبان‌های مانند Python یا Java)، ممکن است حافظه اضافی برای 403 | 404 | مدیریت ظرفیت اضافی در نظر گرفته شود. 405 | • لیست‌های پیوندی: 406 | • لیست‌های پیوندی علاوه بر داده‌ها، به حافظه اضافی برای ذخیره اشاره‌گرهای هر گره نیاز دارند. بنابراین پیچیدگی فضایی برای یک لیست پیوندی به صورت O(n) است، اما با توجه به اینکه برای هر گره نیاز به حافظه اضافی برای اشاره‌گرها داریم، می‌توان گفت که هر گره نیاز به حافظه بیشتری نسبت به یک عنصر آرایه دارد. 407 | • پشته‌ها و صف‌ها: 408 | • پشته‌ها و صف‌ها معمولاً از لیست‌های پیوندی یا آرایه‌ها برای ذخیره داده‌ها استفاده می‌کنند. بنابراین، پیچیدگی فضایی برای این ساختارها به‌طور معمول O(n) است، که در آن n تعداد داده‌هایی است که در پشته یا صف ذخیره شده‌اند. 409 | • دیکشنری‌ها (جداول هش): 410 | • جداول هش به‌طور معمول حافظه زیادی مصرف می‌کنند چون برای ذخیره‌سازی داده‌ها از جداول هش استفاده می‌شود که در آن هر داده یک کلید و مقدار دارد. پیچیدگی فضایی برای دیکشنری‌ها به‌طور معمول O(n) است، که در آن n تعداد جفت‌های کلید-مقدار است. 411 | • در صورت استفاده از روش‌های خاص برای مدیریت برخوردها، مانند زنجیره‌سازی، حافظه مصرفی ممکن است افزایش یابد. 412 | 413 | • گراف‌ها: 414 | • پیچیدگی فضایی گراف‌ها بستگی به نحوه ذخیره‌سازی آن‌ها دارد. در ماتریس مجاورت، پیچیدگی فضایی O(V^2) است، که در آن V تعداد گره‌ها است، زیرا به تعداد زیادی خانه‌های ماتریس برای ذخیره‌سازی اطلاعات نیاز است. 415 | • در لیست مجاورت، پیچیدگی فضایی معمولاً O(V + E) است، که در آن V تعداد گره‌ها و E تعداد یال‌ها است، زیرا باید برای هر گره لیستی از یال‌های مجاور آن ذخیره شود. 416 | 1.5.3. تفاوت پیچیدگی زمانی و فضایی 417 | پیچیدگی زمانی و پیچیدگی فضایی دو جنبه مختلف از عملکرد یک ساختمان داده یا الگوریتم هستند و باید در طراحی و انتخاب الگوریتم‌ها به‌طور همزمان در نظر گرفته شوند. 418 | • پیچیدگی زمانی به سرعت اجرای الگوریتم مربوط می‌شود و مشخص می‌کند که چقدر سریع الگوریتم در هنگام افزایش تعداد ورودی‌ها عمل می‌کند. 419 | • پیچیدگی فضایی به میزان حافظه مصرفی الگوریتم مرتبط است و مشخص می‌کند که الگوریتم چقدر حافظه برای انجام عملیات نیاز دارد. 420 | در بسیاری از موارد، بهینه‌سازی یک بعد (زمان یا فضا) می‌تواند به هزینه دیگری تمام شود. به‌عنوان مثال، برخی از الگوریتم‌ها ممکن است زمان کمتری مصرف کنند ولی فضای 421 | 422 | بیشتری استفاده کنند، یا بالعکس. 423 | جمع‌بندی 424 | تحلیل پیچیدگی زمانی و فضایی، بخش اساسی هر الگوریتم و ساختمان داده است. این تحلیل به برنامه‌نویس کمک می‌کند تا در مواجهه با داده‌های بزرگ، انتخاب‌های بهینه‌تری داشته باشد و کارایی و عملکرد سیستم را در شرایط واقعی بهتر درک کند. این مفاهیم به‌ویژه در حل مسائل مقیاس‌پذیر و بهینه‌سازی الگوریتم‌ها و ساختارهای داده کاربرد فراوانی دارند. 425 | 426 | 427 | 428 | 1.6. نتیجه‌گیری 429 | در این فصل، مفاهیم پایه‌ای ساختمان داده‌ها مانند تعریف، اهمیت، ارتباط با الگوریتم‌ها و پیچیدگی‌های زمانی و فضایی را بررسی کردیم. این مفاهیم از ارکان اصلی هر سیستم نرم‌افزاری به‌شمار می‌آیند و فهم صحیح آنها می‌تواند باعث بهینه‌سازی در طراحی و پیاده‌سازی نرم‌افزارها شود. در فصول بعدی، به‌طور عمیق‌تر به بررسی انواع ساختمان داده‌ها و کاربردهای آنها خواهیم پرداخت. 430 | 431 | نتیجه‌گیری 432 | در این فصل، تلاش کردیم تا مفاهیم اساسی ساختمان داده‌ها و تحلیل پیچیدگی‌های آن‌ها را به‌طور عمیق و کاربردی بررسی 433 | 434 | کنیم. ساختمان داده‌ها، به‌عنوان ابزارهایی برای ذخیره‌سازی و مدیریت داده‌ها، پایه و اساس بسیاری از الگوریتم‌ها و سیستم‌ها هستند. در این فصل، به‌طور خاص به معرفی انواع ساختمان داده‌ها، ویژگی‌های آن‌ها، کاربردها و نحوه انتخاب مناسب‌ترین ساختار داده برای حل مسائل پرداخته‌ایم. همچنین، تحلیل پیچیدگی‌های زمانی و فضایی برای ارزیابی عملکرد الگوریتم‌ها و ساختمان داده‌ها در شرایط مختلف نیز مورد بررسی قرار گرفت. 435 | 436 | نکات کلیدی که در این فصل پوشش داده شد: 437 | • انواع ساختمان داده‌ها: 438 | • آرایه‌ها: آرایه‌ها ساده‌ترین و ابتدایی‌ترین ساختارهای داده هستند که دسترسی سریع به عناصر با ایندکس‌های ثابت را فراهم می‌کنند. اما محدودیت‌هایی مانند اندازه ثابت و نیاز به جابجایی داده‌ها در عملیات‌هایی مانند حذف و افزودن دارند. 439 | • لیست‌های پیوندی: برخلاف آرایه‌ها، لیست‌های پیوندی از حافظه به‌صورت داینامیک استفاده می‌کنند و عملیات‌هایی مانند افزودن و حذف از ابتدا یا انتهای لیست را در زمان ثابت انجام می‌دهند. با این حال، دسترسی به عناصر در این ساختارها کندتر است. 440 | • پشته‌ها و صف‌ها: این ساختارها برای ذخیره‌سازی داده‌ها به‌صورت ترتیبی طراحی شده‌اند و در الگوریتم‌هایی که 441 | 442 | نیاز به پردازش داده‌ها به صورت آخرین ورودی، اولین خروجی (LIFO) یا اولین ورودی، اولین خروجی (FIFO) دارند، مفید هستند. 443 | • دیکشنری‌ها (جداول هش): جداول هش اجازه می‌دهند تا با استفاده از کلیدهای یکتا به سرعت به مقادیر مورد نظر دسترسی پیدا کنیم. این ساختار داده برای پیاده‌سازی سیستم‌های کش، ذخیره‌سازی داده‌ها و انجام جستجوهای سریع استفاده می‌شود. 444 | • گراف‌ها: گراف‌ها برای مدل‌سازی روابط پیچیده میان داده‌ها و انجام الگوریتم‌های مسیریابی، جستجو و پیمایش در شبکه‌های پیچیده مفید هستند. 445 | • ویژگی‌ها و کاربردها: 446 | • هر ساختمان داده ویژگی‌ها و کاربردهای خاص خود را دارد. برای مثال، آرایه‌ها برای دسترسی سریع به داده‌ها مناسب‌اند، اما در مواردی که نیاز به افزودن یا حذف داده‌ها به طور مکرر باشد، لیست‌های پیوندی یا دیکشنری‌ها می‌توانند انتخاب بهتری باشند. 447 | • همچنین، گراف‌ها برای مدل‌سازی سیستم‌هایی مانند شبکه‌های اجتماعی، شبکه‌های حمل‌ونقل یا الگوریتم‌های مسیریابی مناسب هستند. 448 | • پیچیدگی زمانی و فضایی: 449 | • در انتخاب ساختمان داده، پیچیدگی زمانی و فضایی دو عامل حیاتی برای تصمیم‌گیری هستند. پیچیدگی زمانی مشخص می‌کند که الگوریتم یا عملیات در برابر افزایش 450 | 451 | حجم داده‌ها چقدر سریع اجرا می‌شود. از طرف دیگر، پیچیدگی فضایی نشان‌دهنده میزان حافظه مصرفی الگوریتم یا ساختمان داده است. 452 | • در این فصل، نحوه محاسبه و تحلیل این پیچیدگی‌ها برای انواع مختلف ساختمان داده‌ها مورد بحث قرار گرفت. به‌طور کلی، ساختمان داده‌هایی مانند دیکشنری‌ها و جداول هش معمولاً پیچیدگی زمانی ثابت دارند (O(1))، در حالی که ساختارهایی مانند گراف‌ها و لیست‌های پیوندی ممکن است به پیچیدگی زمانی خطی (O(n)) یا حتی مربعی (O(n^2)) برسند. 453 | • انتخاب بهینه ساختمان داده: 454 | • انتخاب مناسب‌ترین ساختمان داده بستگی به ماهیت مشکل و نیازمندی‌های خاص الگوریتم دارد. به‌طور مثال، اگر به دنبال سرعت در جستجو هستید، دیکشنری‌ها و جداول هش می‌توانند گزینه‌های بهتری باشند، در حالی که اگر نیاز به ذخیره‌سازی داده‌ها با ترتیب خاص دارید، آرایه‌ها یا لیست‌های پیوندی می‌توانند انتخاب‌های مناسبی باشند. 455 | • علاوه بر این، انتخاب بین استفاده از گراف یا آرایه به‌طور مستقیم به پیچیدگی داده‌های روابط و نحوه مدل‌سازی آن‌ها بستگی دارد. 456 | 457 | اهمیت یادگیری ساختمان داده‌ها در دنیای 458 | 459 | مهندسی نرم‌افزار 460 | در دنیای توسعه نرم‌افزار، دانش ساختمان داده‌ها یکی از ارکان اصلی برای نوشتن الگوریتم‌های کارآمد و بهینه است. این دانش نه‌تنها به ما کمک می‌کند که مسائل پیچیده را حل کنیم، بلکه درک بهتری از نحوه مدیریت منابع سیستم‌ها و حافظه خواهیم داشت. به‌عنوان یک توسعه‌دهنده یا مهندس نرم‌افزار، توانایی انتخاب صحیح ساختمان داده‌ها بر اساس نیازهای عملکردی و مقیاس‌پذیری یک سیستم، از اهمیت ویژه‌ای برخوردار است. 461 | • برای مثال، در طراحی سیستم‌های مقیاس‌پذیر که به حجم بالایی از داده‌ها و درخواست‌ها پاسخ می‌دهند، انتخاب ساختار داده‌ای مناسب می‌تواند تأثیر زیادی بر سرعت و عملکرد سیستم داشته باشد. 462 | • همچنین، فهم پیچیدگی‌های زمانی و فضایی برای بهینه‌سازی استفاده از منابع سیستم در موقعیت‌های خاص بسیار ضروری است. در پروژه‌هایی که نیاز به پردازش حجم زیادی از داده‌ها دارند، باید بتوانید به سرعت و به‌طور مؤثر منابع را مدیریت کنید تا از بروز مشکلات کارایی جلوگیری کنید. 463 | 464 | در نهایت 465 | این فصل به‌طور جامع ساختمان داده‌ها و پیچیدگی‌های آن‌ها را در دنیای مهندسی نرم‌افزار بررسی کرد. درک این مفاهیم به 466 | 467 | شما کمک خواهد کرد تا در طراحی سیستم‌های نرم‌افزاری و الگوریتم‌ها، انتخاب‌های هوشمندانه‌ای داشته باشید که به بهبود کارایی، مقیاس‌پذیری و قابلیت نگهداری سیستم‌ها کمک می‌کند. یادگیری ساختمان داده‌ها به شما این امکان را می‌دهد که مشکلات پیچیده‌تر و چالش‌های جدید را با استفاده از بهترین ابزارهای موجود حل کنید و در مسیر تبدیل شدن به یک متخصص حرفه‌ای در مهندسی نرم‌افزار گام بردارید. 468 | 469 | برای هر بخش از فصل اول، می‌توانیم با استفاده از زبان جاوا مثال‌هایی بنویسیم که کاربرد و ویژگی‌های ساختمان داده‌ها و پیچیدگی‌های زمانی و فضایی آن‌ها را به‌خوبی نشان دهد. در اینجا چند مثال برای هر بخش آورده شده است: 470 | 471 | کوت‌ها و نقل قول‌ها برای جاوا 472 | • برای آرایه‌ها: 473 | • "آرایه‌ها ساختار داده‌ای هستند که به شما این امکان را می‌دهند که به داده‌ها با استفاده از ایندکس‌های ثابت دسترسی سریع داشته باشید، اما در صورت نیاز به تغییر اندازه، باید یک آرایه جدید ایجاد کنید." 474 | • برای لیست‌های پیوندی: 475 | • "در لیست‌های پیوندی، داده‌ها به‌صورت پیوسته ذخیره می‌شوند و برای پیمایش باید از گره به گره حرکت کنید، که این موضوع باعث می‌شود عملیات دسترسی به 476 | 477 | عناصر کندتر از آرایه‌ها باشد." 478 | • برای پشته‌ها: 479 | • "پشته‌ها ساختارهایی هستند که فقط به بالاترین عنصر اجازه دسترسی می‌دهند، و این ویژگی باعث می‌شود که آن‌ها برای حل مسائلی مانند مدیریت تاریخچه عملیات یا پردازش عمیق‌ترین داده‌ها مفید باشند." 480 | • برای دیکشنری‌ها: 481 | • "دیکشنری‌ها، یا جداول هش، برای ذخیره‌سازی داده‌ها به‌صورت جفت کلید-مقدار طراحی شده‌اند و امکان جستجوی سریع را با استفاده از کلید فراهم می‌کنند." 482 | • برای گراف‌ها: 483 | • "گراف‌ها ابزارهایی هستند که برای مدل‌سازی ارتباطات پیچیده بین داده‌ها استفاده می‌شوند. از آن‌ها در مسائلی مانند شبکه‌های اجتماعی، مسیریابی و جستجوهای گرافی استفاده می‌شود." 484 | این کدها و نقل‌قول‌ها می‌توانند به‌عنوان مثال‌های عملی و توضیحات کلیدی در کتاب شما استفاده شوند تا مفاهیم ساختمان داده‌ها به‌خوبی درک شوند. 485 | -------------------------------------------------------------------------------- /Steps/FirstDay.md: -------------------------------------------------------------------------------- 1 | # First Day 2 | I am in the process of learning Java with a focus on System Design and Software Architecture. My primary goal is to understand how Java can be applied effectively in these areas, especially for those with experience in other programming languages who are just starting to learn Java. 3 |
4 | To support this, I’ve created a repository to share the resources and materials I am working through. This repository aims to help those who are new to Java but have a background in software engineering, system design, architecture, and security. 5 |
6 | The content is organized into four main sections: 7 | 8 | **Software Engineering** - Key concepts and best practices in software development using Java.
9 | **System Design** - Exploring system design patterns, scalability, and how to implement them in Java.
10 | **Architecture** - Understanding Java's role in building robust and scalable architectures.
11 | **Security** - Focusing on secure coding practices, encryption, and other security considerations within Java applications.
12 | I hope this repository will be useful for anyone transitioning to Java from other programming languages, and will serve as a helpful resource for learning and applying Java in these key areas.
13 |
14 | 15 | ## Java Developer Job Roles 16 | # Java developer roles will vary greatly depending on companies and job positions. Here are some typical roles and responsibilities of java developers: 17 | 18 | Contribute to all stages of software development lifecycle
19 | Design, implement and maintain Java-based applications that can be high-volume and low-latency
20 | Analyze user requirements to define business objectives
21 | Envisioning system features and functionality
22 | Define application objectives and functionality
23 | Ensure application designs conform with business goals
24 | Develop and test software
25 | Identify and resolve any technical issues arising
26 | Create detailed design documentation
27 | Propose changes to current Java infrastructure
28 | Develop technical designs for application development
29 | Develop multimedia applications
30 | Write well designed, testable code
31 | Conducting software analysis, programming, testing, and debugging
32 | Manage Java and Java EE application development
33 | Develop documentation to help users
34 | Transforming requirements into stipulations
35 | Prepare and produce releases of software components
36 | Support continuous improvement, investigating alternatives and technologies, and presenting for architectural review. 37 |
38 | 39 | ## Detailed Breakdown of Java Developer Job Description Duties
40 | # Program Architecture 41 | A key function that Java Developers provide during project development 42 |
43 | # Requirement Gathering 44 | The first step to working on a project is to gather requirements from all involved, prioritize important tasks, determine the scope of work on the whole and course of action. 45 |
46 | # Development 47 | In this phase, the Java developer writes the program code, tests it, and makes changes if needed 48 |
49 | # Testing 50 | This duty involves testing and debugging each feature after it is completed. 51 |
52 | # Deployment 53 | In this phase, fully functional code is transferred to a live environment 54 |
55 | Other java developer responsibilities include Software maintenance and optimization, project management, leading and liaising, and vendor management. 56 | 57 | ## Java Developer Skills 58 | # Java Developers need an extensive range of skills, from in-depth knowledge of the basics to a thorough understanding of the current developments. Experts in Java are also expected to know how the development process works and how to transition between the environments where the code runs. 59 | 60 | A well-rounded Java Developer has proficiency in Java full stack developer skills and Java backend developer skills. 61 | 62 | Some of the Java Developer key skills include: 63 | 64 | Proficiency in Java, with a good understanding of its ecosystems
65 | Sound knowledge of Object-Oriented Programming (OOP) Patterns and Concepts
66 | Familiarity with different design and architectural patterns
67 | Skill for writing reusable Java libraries
68 | Knowhow of Java concurrency patterns
69 | Basic Understanding of the concepts of MVC (Model-View-Controller) Pattern, JDBC (Java Database Connectivity), and RESTful web services
70 | Experience in working with popular web application frameworks like Play and Spark
71 | Relevant Knowledge of Java GUI frameworks like Swing, SWT, AWT according to project requirements
72 | Ability to write clean, readable Java code
73 | Basic knowhow of class loading mechanism in Java
74 | Experience in handling external and embedded databases
75 | Understanding basic design principles behind a scalable application
76 | Skilled at creating database schemas that characterize and support business processes
77 | Basic knowledge of JVM (Java Virtual Machine), its drawbacks, weaknesses, and workarounds
78 | Implementing automated testing platforms and unit tests
79 | In-depth knowledge of code versioning tools, for instance, Git
80 | Understanding of building tools like Ant, Maven, Gradle, etc
81 | Expertise in continuous integration
82 | 83 | # Other required skills of java developer include the basic knowledge of: 84 | 85 | JavaServer pages (JSP) and servlets
86 | Web frameworks like Struts and Spring
87 | Service-oriented architecture
88 | Web Technologies like HTML, JavaScript, CSS, JQuery
89 | Markup Languages such as XML, JSON
90 | Abstract classes and interfaces
91 | Constructors, lists, maps, sets
92 | File IO and serialization
93 | Exceptions
94 | Generics
95 | Java Keywords like static, volatile, synchronized, transient, etc
96 | Multithreading and Synchronization
97 | 98 | ## Common Challenges in Object-Oriented Design (OOD)
99 | Designing for potential future needs that may never arise, which adds needless complexity.
100 | Impact: Leads to code that is harder to understand, maintain, and extend.
101 | Mitigation: Focus on current requirements and implement extensibility only when there’s a clear need.
102 | Not foreseeing future demands and modifications, which leads to an inflexible system.
103 | Impact: Makes the system difficult to extend or modify.
104 | Mitigation: Apply principles like SOLID and design patterns that facilitate flexibility and scalability.
105 | Ensuring that encapsulation does not excessively degrade performance.
106 | Impact: Encapsulation can lead to additional layers of abstraction that may impact performance.
107 | Mitigation: Use encapsulation judiciously and optimize critical performance paths as needed.
108 | Determining the right level of abstraction to balance simplicity and functionality.
109 | Impact: Too much abstraction can obscure functionality; too little can lead to code duplication.
110 | Mitigation: Aim for clear and concise abstractions that accurately represent the problem domain.
111 | Common Anti-Patterns in Object-Oriented Design (OOD)
112 | God Object/Anti-Pattern: A single class takes on too many responsibilities, violating the Single Responsibility Principle.
113 | Spaghetti Code: Code with a complex and tangled control structure, making it difficult to follow and maintain.
114 | Lava Flow: Dead code, outdated design elements, and obsolete components that remain in the codebase.
115 | Object Orgy:Excessive sharing of data and methods between classes, leading to tight coupling and lack of encapsulation.
116 | 117 | -------------------------------------------------------------------------------- /Steps/FourDayOOP.md: -------------------------------------------------------------------------------- 1 | ## اصول طراحی شی‌گرا (OOP) را می‌توان به چهار بخش اصلی تقسیم کرد:
2 | 3 | # ۱. مفاهیم پایه‌ای OOP و اهمیت آن
4 | شیء و کلاس چیست؟ (Object & Class)
5 | تفاوت برنامه‌نویسی شی‌گرا با سایر پارادایم‌های برنامه‌نویسی
6 | مزایای OOP: مقیاس‌پذیری، خوانایی، قابلیت نگهداری
7 | # ۲. چهار اصل اساسی OOP
8 | 9 | کپسوله‌سازی (Encapsulation):
10 | تعریف و مفهوم
11 | متدها و سطح دسترسی (private, public, protected)
12 | مثال‌هایی از پیاده‌سازی در جاوا
13 | 14 | # انتزاع (Abstraction):
15 | تعریف و تفاوت آن با کپسوله‌سازی
16 | کلاس‌های انتزاعی (Abstract Classes) و اینترفیس‌ها (Interfaces)
17 | پیاده‌سازی در جاوا
18 | 19 | # وراثت (Inheritance):
20 | مفهوم و مزایای وراثت
21 | نحوه پیاده‌سازی وراثت در جاوا (extends, super)
22 | استفاده صحیح از وراثت و مشکلات احتمالی
23 | 24 | پلی‌مورفیسم (Polymorphism):
25 | مفهوم پلی‌مورفیسم و انواع آن (Compile-time vs Runtime)
26 | متد Overloading و Overriding
27 | پیاده‌سازی در جاوا
28 | -------------------------------------------------------------------------------- /Steps/SecondDay.md: -------------------------------------------------------------------------------- 1 | ## مبتدی 2 | 3 | # سیستم دیزاین و معماری نرم‌افزار: 4 | **آشنایی با اصول طراحی شی‌گرا (OOP)**: 5 | مهندسان نرم‌افزار باید اصول طراحی شی‌گرا مانند وراثت، پلی‌مورفیسم، انتزاع و کپسوله‌سازی را درک کنند تا کدهایی مقیاس‌پذیر و قابل نگهداری بنویسند. 6 | 7 | **الگوهای طراحی نرم‌افزار**: 8 | آشنایی با الگوهای طراحی متداول مانند Singleton, Factory, Observer, Strategy و Adapter برای حل مسائل معمول در معماری نرم‌افزار در پروژه‌ها. 9 | 10 | **درک معماری‌های مدرن مانند Microservices**: 11 | مهندسان باید با معماری‌های میکروسرویس و نحوه تقسیم سیستم به سرویس‌های کوچک و مستقل آشنا شوند. 12 | 13 | **مدیریت وابستگی‌ها (Dependency Injection)**: 14 | استفاده از اصول مدیریت وابستگی‌ها در فریم‌ورک‌هایی مثل Spring، تا کد انعطاف‌پذیر و تست‌پذیر ایجاد شود. 15 | 16 | **استفاده از فریم‌ورک‌ها و کتابخانه‌ها**: 17 | آشنایی با فریم‌ورک‌هایی مانند Spring Boot برای توسعه سریع نرم‌افزار و تسهیل در پیاده‌سازی معماری‌های مختلف. 18 | 19 | # امنیت نرم‌افزار: 20 | آشنایی با اصول امنیتی نرم‌افزار: شناخت مفاهیمی مثل احراز هویت (Authentication)، مجوزدهی (Authorization)، و حفظ امنیت داده‌ها در برنامه‌های جاوا. 21 | 22 | **استفاده از HTTPS و TLS**: 23 | مهندسان نرم‌افزار باید بدانند چگونه از پروتکل HTTPS و TLS برای رمزگذاری ارتباطات و محافظت از داده‌ها استفاده کنند. 24 | 25 | **پیشگیری از حملات SQL Injection**: 26 | مهندسان باید روش‌هایی مانند استفاده از PreparedStatement برای پیشگیری از حملات SQL Injection در برنامه‌های جاوا را یاد بگیرند. 27 | 28 | **مفاهیم مدیریت جلسات (Session Management)**: 29 | آشنایی با نحوه مدیریت جلسات کاربر (مثل استفاده از توکن‌های JWT) و حفاظت از نشست‌ها در برابر حملات امنیتی مانند حملات CSRF. 30 | 31 | **مفاهیم رمزنگاری (Cryptography)**: 32 | آشنایی با الگوریتم‌های رمزنگاری مانند AES و RSA و استفاده از آن‌ها در برنامه‌های جاوا برای حفاظت از اطلاعات حساس. 33 | 34 | 35 | ## متوسط 36 | 37 | # سیستم دیزاین و معماری نرم‌افزار: 38 | **طراحی سیستم‌های مقیاس‌پذیر**: مهندسان نرم‌افزار باید توانایی طراحی سیستم‌هایی با قابلیت مقیاس‌پذیری بالا داشته باشند. این شامل مدیریت بار (load balancing)، استفاده از کش (caching) و تقسیم‌بندی پایگاه داده‌ها (sharding) می‌شود. 39 | 40 | **طراحی معماری سرویس‌گرا (SOA)**: 41 | در این سطح، مهندس باید بتواند معماری سرویس‌گرا (SOA) را طراحی کند که شامل ساخت سرویس‌های مستقل و ارتباط آن‌ها از طریق پروتکل‌های استاندارد مانند SOAP یا REST باشد. 42 | 43 | **مدیریت داده‌های توزیع‌شده (Distributed Systems)**: درک و پیاده‌سازی مفاهیمی مانند replication، consistency، partition tolerance (CAP Theorem) و استفاده از ابزارهای مرتبط مثل Apache Kafka یا RabbitMQ برای ارتباط میان میکروسرویس‌ها و مدیریت داده‌ها. 44 | 45 | **مدیریت پیکربندی با ابزارهای مدرن**: 46 | استفاده از ابزارهایی مانند Spring Cloud Config، Consul، یا Kubernetes برای مدیریت و پیکربندی تنظیمات در سیستم‌های بزرگ و توزیع‌شده. 47 | 48 | تست معماری و مقیاس‌پذیری: توانایی انجام تست‌های معماری برای اطمینان از عملکرد صحیح سیستم در شرایط بار بالا، از جمله تست‌های load testing و stress testing. 49 | 50 | # امنیت نرم‌افزار: 51 | **حفاظت در برابر حملات XSS و CSRF**: 52 | درک و پیاده‌سازی روش‌های پیشگیری از حملات Cross-Site Scripting (XSS) و Cross-Site Request Forgery (CSRF) در برنامه‌های وب جاوا، از جمله استفاده از فریم‌ورک‌های امنیتی مانند Spring Security. 53 | 54 | **مدیریت توکن‌ها و احراز هویت پیشرفته**: 55 | آشنایی با سیستم‌های احراز هویت پیشرفته مثل OAuth 2.0 و OpenID Connect، و توانایی پیاده‌سازی سیستم‌های Single Sign-On (SSO) و مدیریت توکن‌ها مانند JWT در برنامه‌های جاوا. 56 | 57 | **استفاده از معماری Zero Trust**: 58 | پیاده‌سازی اصول معماری Zero Trust که در آن هیچ‌یک از بخش‌ها یا کاربران بدون احراز هویت و مجوز معتبر به سیستم‌ها دسترسی ندارند. 59 | 60 | **آزمون امنیتی و تحلیل آسیب‌پذیری**: 61 | توانایی انجام تست‌های امنیتی مثل تست نفوذ (penetration testing) و تحلیل آسیب‌پذیری‌های نرم‌افزاری برای شناسایی نقاط ضعف امنیتی و رفع آن‌ها. 62 | 63 | **رمزنگاری پیچیده**: 64 | درک مفاهیم رمزنگاری پیشرفته مثل الگوریتم‌های Hashing (SHA-256, bcrypt) و دیجیتال امضاها (digital signatures) و استفاده از کتابخانه‌های امنیتی جاوا مانند BouncyCastle برای پیاده‌سازی آن‌ها. 65 | 66 | 67 | ## حرفه‌ای 68 | # سیستم دیزاین و معماری نرم‌افزار: 69 | **طراحی معماری مقیاس‌پذیر و انعطاف‌پذیر با استفاده از الگوهای پیشرفته**: 70 | مهندسان حرفه‌ای باید توانایی طراحی سیستم‌های پیچیده با معماری‌هایی مانند Event-Driven Architecture یا CQRS (Command Query Responsibility Segregation) و SAGA داشته باشند که قادر به مدیریت فرآیندهای بلند مدت و پیچیده در سیستم‌های توزیع‌شده هستند. 71 | 72 | **پیاده‌سازی معماری میکروسرویس‌های قابل مقیاس‌پذیر**: 73 | مهندسان باید توانایی پیاده‌سازی میکروسرویس‌هایی با مقیاس‌پذیری بالا با استفاده از ابزارهایی مثل Kubernetes, Docker, و Service Mesh داشته باشند، که در مدیریت پیچیدگی‌های میکروسرویس‌ها و هماهنگی بین آن‌ها کمک می‌کند. 74 | 75 | **مدیریت چرخه عمر نرم‌افزار (Software Lifecycle Management)**: 76 | توانایی مدیریت و پیاده‌سازی فرآیندهای DevOps به طور کامل، از جمله اتوماسیون، استقرار پیوسته (Continuous Deployment)، تست خودکار، و نظارت بر سیستم‌های تولیدی با استفاده از ابزارهایی مانند Jenkins, GitLab CI/CD, Prometheus, و Grafana. 77 | 78 | استفاده از الگوهای طراحی غیرهمزمان و معماری Reactive: آشنایی با معماری‌های Reactive Programming (مانند Reactive Streams, Project Reactor, RxJava) برای طراحی سیستم‌هایی که مقیاس‌پذیری و پاسخگویی بالایی دارند و قادر به مدیریت حجم بالای داده‌ها به صورت غیرهمزمان هستند. 79 | 80 | **پیاده‌سازی و مدیریت سیستم‌های توزیع‌شده با Consistency Models پیشرفته**: 81 | توانایی طراحی سیستم‌های توزیع‌شده که نیاز به مدیریت داده‌ها با مدل‌های Eventual Consistency و Strong Consistency دارند، و استفاده از پروتکل‌هایی مانند Paxos و Raft برای هماهنگ‌سازی و اعتبارسنجی داده‌ها. 82 | 83 | # امنیت نرم‌افزار: 84 | **طراحی و پیاده‌سازی سیستم‌های امنیتی پیچیده با استفاده از فریم‌ورک‌های پیشرفته**: 85 | توانایی طراحی سیستم‌های امنیتی مبتنی بر Spring Security یا فریم‌ورک‌های مشابه برای پیاده‌سازی مکانیزم‌های پیچیده مثل Role-based Access Control (RBAC) و Attribute-based Access Control (ABAC). 86 | 87 | **استفاده از روش‌های امنیتی برای جلوگیری از حملات Zero-Day و Advanced Persistent Threats (APT)**: 88 | مهندسان حرفه‌ای باید قادر به شناسایی، پیشگیری، و پاسخ به تهدیدات پیچیده مانند حملات Zero-Day و APT با استفاده از فناوری‌های تحلیل رفتار، نظارت امنیتی و ابزارهای شبیه‌سازی حملات باشند. 89 | 90 | **مدیریت هویت و مجوزدهی در مقیاس بزرگ**: 91 | پیاده‌سازی راهکارهای Identity and Access Management (IAM) با استفاده از استانداردهای OAuth 2.0, OpenID Connect, SAML و Kerberos برای مدیریت هویت در محیط‌های پیچیده و با مقیاس بالا. 92 | 93 | **پیاده‌سازی استانداردهای امنیتی مانند PCI DSS و GDPR در برنامه‌های جاوا**: 94 | توانایی طراحی سیستم‌هایی که قوانین و استانداردهای امنیتی بین‌المللی مانند PCI DSS برای پرداخت‌ها و GDPR برای حفاظت از داده‌های شخصی را در نظر بگیرند و این استانداردها را در کد جاوا پیاده‌سازی کنند. 95 | 96 | **تحلیل و مقابله با حملات DDoS و امنیت شبکه**: 97 | مهندسان حرفه‌ای باید توانایی پیاده‌سازی مکانیزم‌های rate-limiting, firewalls, و intrusion detection systems (IDS) برای جلوگیری از حملات Distributed Denial of Service (DDoS) و تهدیدات امنیتی در سطح شبکه داشته باشند. 98 | 99 | -------------------------------------------------------------------------------- /Steps/ThirdDay.md: -------------------------------------------------------------------------------- 1 | زبان جاوا مستقل از پلتفرم است. 2 | ترکیب سیستم عامل و پردازنده پلتفرم است. 3 | کوچک ترین قسمت کد جاوا function است. 4 | هر برنامه باید یک function داشته باشد. 5 | نقطه شروع زبان جاوا function void است. 6 | همه کلاس ها و متد ها باید یک access method داشته باشند. در ابتدای کلاس. 7 | برای نام گذاری کلاس ها از قاعده پاسکال استفاده میکنیم. 8 | برای نام گذاری متغیر ها از قاعده camel notation استفاده میکنیم. 9 | ## کلاس math 10 | کلاسی که abstract باشه روش نمیشه operator new زد. 11 | با Scammer از کاربر ورودی میگیریم. 12 | با میتوان تمام خط های کابر را برگرداند. 13 | در جاوا، تبدیل داده‌ها (Casting) به دو صورت انجام می‌شود: تبدیل صریح (Explicit Casting) و تبدیل ضمنی (Implicit Casting). 14 | بعد از هر case حتما Break قرار بدهیم. 15 | 16 | 17 | فایل‌های **JAR (Java ARchive)** بسته‌های فشرده‌شده‌ای هستند که معمولاً برای ذخیره‌سازی کدهای جاوا و منابع مورد نیاز یک برنامه جاوا به کار می‌روند. فایل‌های JAR می‌توانند شامل کلاس‌های کامپایل‌شده، فایل‌های منابع (مثل تصاویر یا فایل‌های متنی) و حتی متادیتای مربوط به برنامه باشند. 18 |
19 | مزایای استفاده از JAR عبارتند از: 20 |
21 | جمع‌آوری کدهای جاوا: تمام کلاس‌ها و منابع مربوط به یک برنامه را در یک فایل فشرده جمع‌آوری می‌کند.
22 | قابل اجرا بودن: اگر فایل JAR شامل یک فایل manifest باشد و برنامه به‌درستی پیکربندی شده باشد، این فایل می‌تواند به‌عنوان یک برنامه اجرایی استفاده شود (با دستور java -jar).
23 | کاهش حجم: به دلیل فشرده‌سازی فایل‌ها، حجم برنامه کاهش می‌یابد.
24 | سادگی در توزیع: ارسال یک فایل JAR به‌جای ارسال تعداد زیادی فایل جاوا، راحت‌تر است.
25 | برای ساختن یک فایل JAR، می‌توان از ابزارهایی مانند javac و jar که همراه با JDK می‌آیند، استفاده کرد.
26 | 27 | 28 | 29 | 30 | --------------------------------------------------------------------------------