SEARCH RESULTS
88 results found with an empty search
- AI's Expanding Role: Opportunities and Challenges Across Industries
Artificial Intelligence (AI) is set to transform diverse industries, including unexpected sectors like mining, by enhancing efficiency, precision, and safety through advanced data analysis and automation. However, while AI offers promising benefits, its rapid implementation also raises concerns about job displacement and the need for ethical alignment. Alexander S. Ricciardi November 6, 2024 Artificial Intelligence (AI) is expected to have a considerable impact on all industries, directly or indirectly, as early as the beginning of 2025, when the first AI agents will start to be implemented. Eric Schmidt, former Google CEO, AI consultant for the US military, and one of the most influential figures in AI, stated during a speech at Stanford University, that AI “is going to have an impact on the world at a scale that no one can yet fully comprehend” (Financial Wise, 2024, 3:37). In his speech, he used the word “impact” 11 times. The video was later removed by Stanford University because his comments about Google were deemed too controversial; however, the video is all over the internet. Ultimately, the impact of AI on society could be extremely beneficial or extremely damaging, depending on how it is implemented and for what goals. AI is starting to impact industries that may not seem to be ideal candidates for AI implementations. One of these industries is mining. AI-power systems are being introduced to improve mine sites' efficiency by improving resource estimation accuracy. AI can efficiently examine geological data patterns and incorporate historical mining data resulting in more precise estimates of mineral reserves than traditional methods. This can help the mining companies make more informed decisions regarding investment, production planning, and resource allocation (IMAC, 2025). Additionally, “AI has the potential to streamline mining operations and optimize asset management” (IMAC, 2025, p.1). AI can be integrated into Internet of Things (IoT) devices and sensors allowing real-time data collection. This will enable mining companies to monitor equipment performance, evaluate operational metrics, and identify potential bottlenecks. AI can also analyze the collected data to generate insights and predictions that can improve the companies’ decision-making and prevent unplanned downtime. Furthermore, AI-power systems can automate mining systems improving efficiency and safety in mining operations (IMAC, 2025). AI systems are getting better at controlling autonomous vehicles and machinery and becoming more efficient than human operators at performing tasks with precision, navigating complex terrains, and optimizing routes. This could minimize errors and risk of accidents; therefore, improving safety. AI can also monitor equipment health, detect anomalies, and schedule maintenance activities improving uptime and extending the lifespan of mining equipment. However, AI implementation in the mining sector can also have negative effects; particularly the automation of mining systems has the potential to limit employment opportunities and result in layoffs, as it would replace jobs traditionally held by human workers. In other words, the automation of mining operations, from autonomous vehicles to predictive maintenance, from data analyses to robotic drilling and excavation, would inevitably lead to job displacement. This raises troubling and complex questions about AI alignment; that is how AI systems can be developed and implemented to align with societal values and human needs. Thus, it is essential for society to understand those challenges and to ensure that AI implementations are balanced and beneficial not just to companies but to society as a whole. To summarize, AI continues to evolve and is implemented in industries that may not seem to be ideal candidates, such as mining. This demonstrates that AI has the ability to impact all industries in the near future. Additionally, AI has the potential to be extremely beneficial or extremely damaging depending on how society implements AI and for what goals. Thus, it is crucial to ensure that AI implementations are balanced and beneficial not only for companies but also for society as a whole. The words of Eric Schmidt “AI is going to have an impact on the world at a scale that no one can yet fully comprehend” (Financial Wise, 2024, 3:37), resonate as both a warning and a promising future. Eric Schmidt Speech at Stanford University References: Financial Wise. (2024, August 18). Eric Schmidt Full Controversial Interview on AI Revolution (Former Google CEO) [Video]. YouTube. https://www.youtube.com/watch?v=mKVFNg3DEng IMARC (2025, October). From changing a tire to uncovering the next lode: How AI is revolutionizing the mining industry | International Mining and Resources Conference (IMARC). IMAC Global. https://imarcglobal.com/news/articles/how-ai-is-revolutionising-the-mining-industry
- Concurrency in C++: Mitigating Risks
This article explores concurrency in C++ and explains how multithreading can improve application performance while also introducing potential vulnerabilities if not properly managed. It emphasizes the importance of following SEI CERT C++ Coding Standards to prevent issues like data races, deadlocks, and undefined behavior in concurrent programming. Alexander S. Ricciardi November 7, 2024 In computer science, concurrency or multithreading is a powerful that can be used to improve the performance and responsiveness of applications, is especially beneficial to applications needing to handle large amounts of computation or I/O tasks. Concurrency is an approach that allows multiple threads to be executed concurrently on multi-core processors, reducing the program execution time. C++, starting at the C++ 11 release, provides native support for threads such as ‘std::thread’, as well as concurrency control features such as ‘std::mutex’, ‘std::lock_guard’, and ‘unique_lock’. However, concurrency, in C++, also introduces vulnerabilities if not properly managed. An incorrect implementation of concurrency can result in serious issues such as data races, deadlocks, and undefined behavior. Thus, it is imperative to understand how to properly implement and manage threats to avoid potentially serious consequences. This can be done by adhering to best practices such as the one recommended by SEI CERT C++ Coding Standard, Rule 10 Concurrency (CON) (CMU - Software Engineering Institute, n.d.). Below is a list of common concurrency vulnerabilities and the corresponding SEI CERT C++ Coding Standard rules that address them. 1. Data Races: It occurs when two or more threads access shared data simultaneously, and at least one thread modifies the data. This can lead to inconsistent or unexpected results. Accessing shared data in a safe manner by preventing data races is compliant with the SEI CERT C++ Coding Standard CON51-CPP: "Ensure actively held locks are released on exceptional conditions" (CMU - Software Engineering Institute, n.d.). Example 1: Data Race (CON51-CPP) – Code with vulnerability int shared_counter = 0; void increment_counter() { for (int i = 0; i < 1000; ++i) { ++shared_counter; // Data race here } } void dataRaceExample() { std::thread t1(increment_counter); std::thread t2(increment_counter); t1.join(); t2.join(); std::cout << "Counter: " << shared_counter << std::endl; } Solution example: Data protected with mutex std::mutex mtx; int shared_counter = 0; void increment_counter() { for (int i = 0; i < 1000; ++i) { std::lock_guard lock(mtx); ++shared_counter; } } void dataRaceSolution() { std::thread t1(increment_counter); std::thread t2(increment_counter); t1.join(); t2.join(); std::cout << "Counter: " << shared_counter << std::endl;} 2. Deadlocks It happens when two or more threads are waiting indefinitely for resources held by each other, preventing any of them from proceeding. Locking mutexes in a predefined order to avoid deadlocks is compliant with CON53-CPP: "Avoid deadlock by locking in a predefined order" (CMU - Software Engineering Institute, n.d.). Example 2: Deadlock (CON53-CPP) – Code with vulnerability std::mutex mtx1, mtx2; void thread_func1() { // locks mtx1 waits for mtx2 to be released to lock it std::lock_guard lock1(mtx1); // The sleep function allows the other threat to lock the next mutex // While this treat is locking the previous mutex std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::lock_guard lock2(mtx2); std::cout << "Hello from Threat-2\n"; } void thread_func2() { // locks mtx2 waits for mtx1 to be released to lock it std::lock_guard lock2(mtx2); // The sleep function allows the other threat to lock the next mutex // While this treat is locking the previous mutex std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::lock_guard lock1(mtx1); std::cout << "Hello from Threat-2\n"; } void deadlockExample() { std::thread t1(thread_func1); std::thread t2(thread_func2); t1.join(); t2.join(); } Solution: Lock mutexes in a predefined order std::mutex mtx1, mtx2; void thread_func1() { // locks mtx1 waits for mtx2 to be released to lock it std::lock(mtx1, mtx2); // Locks mutexes in a predefine order std::lock_guard lock1(mtx1, std::adopt_lock); std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::lock_guard lock2(mtx2, std::adopt_lock); std::cout << "Hello from Threat-1\n"; } void thread_func2() { // locks mtx2 waits for mtx1 to be released to lock it std::lock(mtx2, mtx1); // Locks mutexes in a predefine order std::lock_guard lock2(mtx2, std::adopt_lock); std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::lock_guard lock1(mtx1, std::adopt_lock); std::cout << "Hello from Threat-2\n"; } void deadlockExample() { std::thread t1(thread_func1); std::thread t2(thread_func2); t1.join(); t2.join(); } 3. Destroying Locked Mutexes Destroying a mutex while it is still locked can lead to undefined behavior and potential resource leaks. Not destroyed mutexes while locked is compliant with CON50-CPP: "Do not destroy a mutex while it is locked" (CMU - Software Engineering Institute, n.d.). Example 3: Destroying locked mutex (CON50-CPP) – Code with vulnerability void mutexDestructionExample() { std::mutex mtx; mtx.lock(); std::cout << "Hello from Threat!"; // Mutex goes out of scope while still locked // causing undefined behavior } Solution: Unlock Mutex Before Destruction void mutexDestructionSolution() { std::mutex mtx; mtx.lock(); std::cout << "Hello from Threat!"; mtx.unlock(); // Making sure that the mutex is unlocked } 4. Incorrect Use of Condition Variables Not wrapping condition variable waits in a loop can lead to spurious wake-ups and incorrect program behavior. Wrapping wait calls in a loop is compliant with CON54-CPP: "Wrap functions that can spuriously wake up in a loop" (CMU - Software Engineering Institute, n.d.). Example 4: Condition variable without loop (CON54-CPP) – Code with vulnerability static std::mutex m;static std::condition_variable condition;bool ready = false;void consume_list_element() { std::unique_lock lk(m); Ready = true; condition.wait(lk /* The condition predicate is not checked */ ); std::cout << "Hello from Threat!"; } Solution: Wrap wait in a loop checking the predicate static std::mutex m; static std::condition_variable condition; bool ready = false; void consume_list_element() { std::unique_lock lk(m); ready = true; while(true){ // The condition predicate is checked condition.wait(lk, [] { return ready; }); std::cout << "Hello from Threat!"; if (ready) { break; } } } 5. Speculative Locking of Non-recursive Mutexes Do not attend to lock a non-recursive mutex that is already locked by the same thread, this can result in undefined behavior and potential deadlocks. Not trying to lock already locked non-recursive mutexes is compliant with CON56-CPP: "Do not speculatively lock a non-recursive mutex that is already owned by the calling thread" (CMU - Software Engineering Institute, n.d.). Example 5: Speculative locking (CON56-CPP) – Code with vulnerability std::mutex mtx; // Not a recursive mutex void recursiveLock() { mtx.lock(); // Do something if (/* some condition */) { recursiveLock(); // causes deadlock } mtx.unlock(); } Solution: Use recursive mutex std::recursive_mutex mtx; // Is a recursive mutex void recursiveLock() { mtx.lock(); // Do something if (/* some condition */) { recursiveLock(); // no deadlock } mtx.unlock(); } 6. Accessing Adjacent Bit-fields from Multiple Threads Accessing bit fields concurrently can result in data race conditions. When accessing bit-fields preventing data races from multiple threads is compliant with CON52-CPP: "Prevent data races when accessing bit-fields from multiple threads" (CMU - Software Engineering Institute, n.d.). Example 6: Bit-field Data Race (CON52-CPP) – Code with vulnerability struct Flags { unsigned int flag1 : 1; unsigned int flag2 : 1; } flags; void setFlag1() { flags.flag1 = 1; } void setFlag2() { flags.flag2 = 1; } Solution: Use separate storage units or protect with mutex std::mutex mtx1, mtx2; struct Flags { unsigned int flag1; unsigned int flag2; } flags; void setFlag1() { std::lock_guard lock(mtx1); flags.flag1 = 1; } void setFlag2() { std::lock_guard lock(mtx2); flags.flag2 = 1; } 7. Thread Safety and Liveness with Condition Variables When using condition variables is essential to ensure thread safety and preserve liveness. Liveness is the process of the threads making continuous progress and does not end up in situations where they are unable to proceed. For example, being indefinitely blocked or waiting for resources that never will become available. Preserving thread safety and liveness is compliant with CON55-CPP: "Preserve thread safety and liveness when using condition variables" (CMU - Software Engineering Institute, n.d.). Below is a table summary of the risk assessment of the C++ concurrency coding rules from the SEI CERT C++ Coding Standard. Table 1 Concurrency Rules Risk Assessment Note: From "Rule 10. Concurrency (CON). SEI CERT C++ Coding Standard" by CMU - Software Engineering Institute (n.d.). Table Description: • Rule: The specific rule from the SEI CERT C++ Coding Standard. • Severity: The potential impact on security. • Likelihood: The probability of the rule violation leading to a vulnerability. • Remediation Cost: The effort required to fix the violation. To summarize, in computer science, concurrency is a powerful tool that can be used to improve the performance and responsiveness of applications. However, in C++, concurrency can introduce vulnerabilities if not properly managed, and it may result in serious issues such as data races, deadlocks, and undefined behavior. Thus, it is imperative to adhere to best practices such as the one recommended by SEI CERT C++ Coding Standard. References: CMU - Software Engineering Institute (n.d.) Rule 10. Rule 10. Concurrency (CON). SEI CERT C++ coding standard. Carnegie Mellon University. Software Engineering Institute. https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=88046460
- Securing C++ iostream: Key Vulnerabilities and Mitigation Strategies
The C++ ' iostream ' library offers flexible input and output operations. However, it also introduces potential security vulnerabilities, including buffer overflows, inconsistent formatting, and thread safety issues. By following best practices such as boundary checks, resetting stream states, and implementing thread safety measures, developers can mitigate these risks effectively. Alexander S. Ricciardi October 31, 2024 In C++, the ‘iostrem’ library is an object-oriented library that provides input and output functionality using streams (cpluplus, n.d.). A stream is an abstraction representing a device on which input and output of operations can be performed. In other words, it is a representation of a source or destination of characters with indefinite length (can handle an unknown or variable amount of data). Streams can be many things, for example, they can handle input and output from a disk file, keyboard, console, or even in-memory strings. The diagram below provides an illustration of the C++ I/O classes and how they relate to each other. Figure 1z C++ I/O Classes Note: The diagram shows the hierarchical structure and relationships between different C++ I/O classes, such as input streams (‘i stream ’), output streams (‘ ostream ’), and file streams (‘ fstream ’), as well as the buffers associated with of them. From “Input/Output” by cpluplus (n.d.). The ‘ iostrem ’ library brings flexibility on how to manipulate input and output operations. However, it also introduces vulnerabilities, especially when formatting input data is handled improperly. Below is a list of the common formatting vulnerabilities that can emerge when using the ‘iostrem’ library. 1. Buffer overflow and data truncation, this can happen by not having a built-in mechanism that checks boundaries (Snyk Security Research Team, 2022). For example, user input can lead to data truncated or bindery overflow when formatting functions like ‘ std::setw ’ are used improperly. Truncated Code example, what not to do: #include #include #include void printInput(const std::string& input) { // Using std::setw without checking input length std::cout << "Formatted Input: " << std::setw(10) << input << std::endl; } int main() { std::string userInput; std::cout << "Enter a word: "; std::cin >> userInput; // This could cause data truncation if input is longer than 10 characters printInput(userInput); return 0; } 2. Inconsistent data formatting , the I/O streams have formatting states that once set need to be reset whenever manipulating the data with different manipulators (Moria, 2017). For example when using a combination of manipulators like ‘ std::hex ’, ‘ std::oct ’, or ‘ std::dec’ . If the states are not reset, the outputs may retain the format of the previous manipulator, resulting in incorrect data representation. Code example, what not to do: #include #include void displayValues() { int number = 255; // std::hex, print the number in hexadecimal format std::cout << "Hexadecimal: " << std::hex << number << std::endl; // Print the number again without resetting the manipulator std::cout << "Decimal (Incorrect): " << number << std::endl; // Correct approach: reset to std::dec for decimal output std::cout << "Decimal (Correct): " << std::dec << number << std::endl; } int main() { displayValues(); return 0; } Output Hexadecimal: ff Decimal (Incorrect): ff Decimal (Correct): 255 3. Stream adjustor side-effects , when using manipulators that adjust stream such as width, precision, or fill characters (e.g., ‘std::setprecision’ , ‘ std::setfill ’), if not used properly, can result in unpredictable results. This can affect the subsequent output throughout the program. Code example, what not to do: #include #include void displayNumbers() { double num1 = 3.14159; double num2 = 42; // Set precision and fill for num1 std::cout << "Formatted num1: " << std::setprecision(4) << std::fixed << num1 << std::endl; // no resetting, these settings affect num2 as well std::cout << "Formatted num2 (Incorrect): " << num2 << std::endl; // Correct approach: reset manipulators for num2 std::cout << "Formatted num2 (Correct): " << std::setprecision(0) << num2 << std::endl; } int main() { displayNumbers(); return 0; } Output: Formatted num1: 3.1416 Formatted num2 (Incorrect): 42.0000 Formatted num2 (Correct): 42 4. Thread safety concerns , ‘ std::cout ’ is thread-safe for individual character operations; However concurrent writes from multiple threads can result in interleaved output, see code example below: Code example, what not to do: #include #include void print_message(const std::string& message) { std::cout << message << std::endl; } int main() { std::thread t1(print_message, "Hello from thread 1"); std::thread t2(print_message, "Hello from thread 2"); t1.join(); t2.join(); return 0; } Output: Hello from thread 1Hello from thread 2 A solution is to add a mutex locks #include #include #include std::mutex cout_mutex; void print_message(const std::string& message) { std::lock_guard lock(cout_mutex); std::cout << message << std::endl; } int main() { std::thread t1(print_message, "Hello from thread 1"); std::thread t2(print_message, "Hello from thread 2"); t1.join(); t2.join(); return 0; } Output: Hello from thread 1Hello from thread 2 All the examples above illustrate vulnerabilities that can be exploited by malicious actors if not properly addressed. Below is a list of tips for identifying and mitigating these vulnerabilities: Use tools for static analysis to detect buffer-related issues, tools such as Polyspace, Astrée, Splint, Asan, etc. These tools are very useful in identifying such vulnerabilities, especially when the source code consists of millions of lines. Enforce data type boundaries by integrating built-in boundary checks into the program code and performing tests to validate that the data is handled properly. After modifying stream states with manipulators, reset them or use local copies of streams. Use proper thread safety by using mechanics such as ‘mutex’ locks when accessing shared resources like in multithreaded applications. To summarize, the ‘ iostrem ’ library is an object-oriented library that provides input and output functionality using streams, it provides flexible input/output operations. However, it also introduces vulnerabilities if not managed carefully. Vulnerabilities like buffer overflow, inconsistent formatting, and thread safety concerns. By applying best practices such as resetting stream states, performing boundary checks, and using thread-safety mechanisms, these Vulnerabilities can be mitigated. References: cpluplus (n.d.). Input/Output. Cpluplus. https://cplusplus.com/reference/iolibrary/ Moria (2017, May 13). IOStream Is Hopelessly Broken. Moria. https://www.moria.us/articles/iostream-is-hopelessly-broken/ Snyk Security Research Team (2022, August 16). Top 5 C++ security risks. Snyk. https://snyk.io/blog/top-5-c-security-risks/
- Creating Java GUIs with Swing Components
This article explores Java's Swing toolkit. A library for building Graphical User Interfaces (GUIs) using components like JFrame, JDialog, and JApplet, which serve as essential top-level containers. It also demonstrates how to create a simple contact form using Swing components. Alexander S. Ricciardi June 18, 2024 Swing is a Java library used to create simple Graphical User Interfaces (GUIs). It is a GUI widget toolkit providing a collection of components for constructing GUIs. (Oracle Docs, n.d.a). Swing components are written entirely in the Java programming language. There are three generally useful top-level container classes: JFrame, JDialog, and JApplet (Oracle Docs, n.d. b). Top-level container: A JFrame is a top-level window with a title and a border. (Oracle Docs, n.d.b, How to Make Frames (Main Windows). A JDialog window is an independent sub-window that temporaries notice apart from the main Swing Application Window. (Oracle Docs, n.d.b, How to Make Dialogs) “ JApplet , a Java applet is a special kind of Java program that a browser enabled with Java technology can download from the internet and run. An applet is typically embedded inside a web page and runs in the context of a browser. An applet must be a subclass of the applet. Applet class. The Applet class provides the standard interface between the applet and the browser environment” (Oracle Docs, n.d.c). Every program that utilizes Swing components includes at least one top-level container. This top-level container serves as the root of a containment hierarchy, which encompasses all the Swing components within the container (Oracle Docs, n.d.b). Typically, a standalone application with a Swing-based GUI will have at least one containment hierarchy with a JFrame as the root. For instance, if an application features a main window and two dialogs, it will have three containment hierarchies, each with its own top-level container. The main window will have a JFrame as its root, while each dialog will have a JDialog as its root.A Swing-based applet also has at least one containment hierarchy, with one rooted by a JApplet object. For example, an applet that displays a dialog will have two containment hierarchies. The components within the browser window belong to a containment hierarchy rooted by a JApplet object, while the dialog belongs to a containment hierarchy rooted by a JDialog object. JComponent Class: Except for top-level containers, all Swing components that start with "J" are derived from the JComponent class. For instance, JPanel, JScrollPane, JButton, and JTable all inherit from JComponent. However, JFrame and JDialog do not, as they are top-level containers (Oracle Docs, n.d.b, The JComponent Class) Differences between Frame and Panel: Frame: A JFrame is a top-level container that represents a window with a title, borders, and buttons. It is typically used as the main window of an application. A JFrame can contain multiple components, including JPanel , JScrollPane , JButton, JTable , and etc. Panel: A JPanel is a generic container that is used to group a set of components together within a window. It does not have window decorations like a title bar or close button. A JPanel is often used to organize and manage layout within a JFrame . Every program that utilizes Swing components includes at least one top-level container. This top-level container serves as the root of a containment hierarchy, which encompasses all the Swing components within the container (Oracle Docs, n.d.b). Typically, a standalone application with a Swing-based GUI will have at least one containment hierarchy with a JFrame as the root. For instance, if an application features a main window and two dialogs, it will have three containment hierarchies, each with its own top-level container. The main window will have a JFrame as its root, while each dialog will have a JDialog as its root. A Swing-based applet also has at least one containment hierarchy, with one rooted by a JApplet object. For example, an applet that displays a dialog will have two containment hierarchies. The components within the browser window belong to a containment hierarchy rooted by a JApplet object, while the dialog belongs to a containment hierarchy rooted by a JDialog object. The example below includes a JFrame and a JPanel , as well as additional components like buttons, text fields, and labels using a GridBagLayout . Moreover, it also displays a message using JDialog , the JOptionPane component, and a Dialog window component. It is a simple graphical user interface (GUI) contact form using Swing components. / /--- Abstract Window Toolkit (AWT) // Provides layout manager for arranging components in five regions: // north, south, east, west, and center. import java.awt.BorderLayout; // Grid layout - Specifies constraints for components that are laid out using the GridBagLayout. import java.awt.GridBagConstraints; // Grid - layout manager that aligns components vertically and horizontally, // without requiring the components to be of the same size. import java.awt.GridBagLayout; // Gird padding - Specifies the space (padding) between components and their borders. import java.awt.Insets; // Button - Provides the capability to handle action events like button clicks . import java.awt.event.ActionEvent; // Button event - Allows handling of action events, such as button clicks. import java.awt.event.ActionListener; //--- swing GUI // Button - Provides a button component that can trigger actions when clicked. import javax.swing.JButton; // Frame - Provides a window with decorations // such as a title, border, and buttons for closing and minimizing. import javax.swing.JFrame; // Labels - Provides a display area for a short text string or an image, or both. import javax.swing.JLabel; // Submition Message - Provides standard dialog boxes such as message, input, and confirmation dialogs. import javax.swing.JOptionPane; // Panel - Provides a generic container for grouping components together. import javax.swing.JPanel; // Scroll user message - Provides to the a scrollable view of a lightweight component. import javax.swing.JScrollPane; // User message - Provides a multi-line area to display/edit plain text. import javax.swing.JTextArea; // Name & Email - Provides a single-line text field for user input. import javax.swing.JTextField; /** * This class generates a simple contact form. The form includes fields for the * user's name, email, and message, and a submit button to submit the form. * * @author Alejandro Ricciardi * @version 1.0 * @date 06/16/2024 */ public class contactForm { /** * The main method to create and display the contact form. * * @param args Command line arguments */ public static void main(String[] args) { /*------------ | Frame | ------------*/ // ---- Initializes frame // Creates the main application frame JFrame frame = new JFrame("Contact Form"); frame.setSize(400, 300); // Set the size of the frame // Close the application when the frame is closed frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); // Use BorderLayout for the frame /*------------ | Panel | ------------*/ // ---- Initializes panel // Create a panel with GridBagLayout JPanel panel = new JPanel(new GridBagLayout()); GridBagConstraints gridForm = new GridBagConstraints(); gridForm.insets = new Insets(5, 5, 5, 5); // Add padding around components // ---- Creates and adds grid components to the panel // -- Name // Adds "Name" label JLabel nameLabel = new JLabel("Name:"); gridForm.gridx = 0; // Position at column 0 gridForm.gridy = 0; // Position at row 0 panel.add(nameLabel, gridForm); // Add text field for name input JTextField nameField = new JTextField(20); gridForm.gridx = 1; // Position at column 1 gridForm.gridy = 0; // Position at row 0 panel.add(nameField, gridForm); // -- Email // Add "Email" label JLabel emailLabel = new JLabel("Email:"); gridForm.gridx = 0; // Position at column 0 gridForm.gridy = 1; // Position at row 1 panel.add(emailLabel, gridForm); // Adds text field for email input JTextField emailField = new JTextField(20); gridForm.gridx = 1; // Position at column 1 gridForm.gridy = 1; // Position at row 1 panel.add(emailField, gridForm); // Adds "Message" label JLabel messageLabel = new JLabel("Message:"); gridForm.gridx = 0; // Position at column 0 gridForm.gridy = 2; // Position at row 2 panel.add(messageLabel, gridForm); // -- Message // Adds text area for message input with a scroll pane JTextArea messageArea = new JTextArea(5, 20); JScrollPane scrollPane = new JScrollPane(messageArea); gridForm.gridx = 1; // Position at column 1 gridForm.gridy = 2; // Position at row 2 panel.add(scrollPane, gridForm); // Adds "Submit" button JButton submitButton = new JButton("Submit"); gridForm.gridx = 1; // Position at column 1 gridForm.gridy = 3; // Position at row 3 panel.add(submitButton, gridForm); // Adds the panel to the frame's center frame.add(panel, BorderLayout.CENTER); // Make the frame visible frame.setVisible(true); /*------------ | JDialog | ------------*/ // Add action listener to the submit button ActionListener submitBtnClicked = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // Display a message dialog when the submit button is clicked JOptionPane.showMessageDialog(frame, "Message was sent!"); } }; submitButton.addActionListener(submitBtnClicked); } } If you are interested to learn more about dialogue windows, the following video describes how to implement a JDialog JOptionPane message: To summarize, Java's Swing toolkit offers a set of components that enable developers to create user-friendly, visually structured GUIs. The library uses top-level containers like JFrame, JDialog, and JApplet, alongside essential elements like JPanel and JOptionPane. References: Oracle Docs. (n.d.a). Swing . Oracle. https://docs.oracle.com/javase/8/docs/technotes/guides/swing/ Oracle Docs. (n.d.b). Using Top-Level Containers . The Java™ Tutorials. Oracle. https://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html Oracle Docs. (n.d.c). Java Applets . The Java™ Tutorials. Oracle. https://docs.oracle.com/javase/tutorial/deployment/applet/index.html
- AI and Machine Learning Algorithms: Strengths, Weaknesses and Best Use Cases
This article provides an overview of AI and Machine Learning algorithms. It lists their strengths, weaknesses, and applications across various fields. It also emphasizes the importance of selecting appropriate algorithms based on specific application needs. Alexander S. Ricciardi October 22, 2024 Machine Learning (ML) is an application of Artificial Intelligence (AI). Microsoft defines AI as “the capability of a computer system to mimic human cognitive functions such as learning and problem-solving. Through AI, a computer system uses math and logic to simulate the reasoning that people use to learn from new information and make decisions” (Microsoft, n.d.). ML can be defined as an application of AI. "It’s the process of using mathematical models of data to help a computer learn without direct instruction. This enables a computer system to continue learning and improving on its own, based on experience” (Microsoft, n.d.). AI and ML algorithms are used to solve complex problems across a large variety of industries. Each algorithm is better suited for certain tasks than others, each with its strengths and weaknesses. Thus, selecting the appropriate algorithm that meets the specific needs of an application is essential. This post explores the different types of AI and ML strengths, weaknesses, and the specific applications for which they are best suited to solve problems. The field of AI utilizes a substantial number of algorithms. The table below lists some of them with their descriptions: Table 1 AI Algorithms Note: Data adapted from multiple sources: (Baheti, 2024; Baluja, 2024; Biswal, 2024; Boesch, 2024; Lui et al., 2018; Kerner, 2024; Tableau, n.d.; & Vargas et al., 2023) The algorithms in Table 1 can be further categorized into seven different categories as follows: Supervised Learning Algorithms (ML-specific) : Regression, Logistic Regression, Decision Trees, Random Forest, and Support Vector Machines (SVM). “Supervised Learning is a technique that is widely used in various fields such as finance, healthcare, marketing, and more. In supervised learning, the supervised learning algorithm learns a mapping between the input features and output labels” (Gupta, 2024) Unsupervised Learning Algorithms (ML-specific) : K-Means Clustering, Hierarchical Clustering, and Principal Component Analysis (PCA). “Unsupervised learning is a type of machine learning in which models are trained using unlabeled dataset and are allowed to act on that data without any supervision” (JavaPoints, n.d.) Neural Networks and Deep Learning (ML and AI) : Convolutional Neural Networks (CNNs), Recurrent Neural Networks (RNNs), and Generative Adversarial Networks (GANs). “Neural Networks are one particular type of Machine Learning technique. They are a type of artificial intelligence modeled on the brain. There are nodes or artificial neurons that are each responsible for a simple computation. These nodes are networked together with connections of varying strengths, and learning is reflected in changes to those connections. An important characteristic of neural networks is the relationship between nodes. Often, there is an input layer, an output layer, and one or more in between layers (called “hidden layers”), which can result in a model that has a lot of complexity, but may be difficult to interpret” (Network of the National Library of Medicine, n.d.) Reinforcement Learning (AI-specific): Q-Learning, Deep Q-Networks (DQN), and Proximal Policy Optimization (PPO). “Reinforcement learning (RL) is a type of machine learning process that focuses on decision making by autonomous agents. An autonomous agent is any system that can make decisions and act in response to its environment independent of direct instruction by a human user. Robots and self-driving cars are examples of autonomous agents. In reinforcement learning, an autonomous agent learns to perform a task by trial and error in the absence of any guidance from a human user. It particularly addresses sequential decision-making problems in uncertain environments, and shows promise in artificial intelligence development” (Murel, & Kavlakoglu, 2024) Optimization Algorithms (Used in ML and AI) : Gradient Descent, Adam, and Simulated Annealing. “Optimization algorithms are a class of algorithms that are used to find the best possible solution to a given problem. The goal of an optimization algorithm is to find the optimal solution that minimizes or maximizes a given objective function” (Complexica, n.d.). Probabilistic and Evolutionary Models (ML-specific and used in AI): Bayesian Networks, Markov Chain Monte Carlo (MCMC), and Evolutionary Algorithms (Genetic Algorithms). “Probabilistic models are an essential component of machine learning, which aims to learn patterns from data and make predictions on new, unseen data. They are statistical models that capture the inherent uncertainty in data and incorporate it into their predictions” (Visha, 2023) Other: Autoencoders, Transfer Learning, t-SNE, and Fuzzy Logic Algorithms. They are used for specialized tasks. Tasks such as feature extraction, knowledge transfer, dimensionality reduction, and reasoning under uncertainty. AI algorithms have their strengths and weaknesses, which make them suitable and efficient for certain tasks and less suitable and efficient for others. The table below lists the strengths and weaknesses of different AI-ML algorithms, as well as, the applications for which they are best suited. Table-2 AI-ML Algorithms Strengths, Weaknesses, and Applications Note: Data adapted from “A Review of Artificial Intelligence Algorithms Used for Smart Machine Tools” by Lui et al. (2018). As illustrated in Table 2, different AI Algorithms are better suited for specific tasks generally based on their accuracy, efficiency, scalability, and robustness. For example, Long Short-Term Memory (LSTMs) algorithms are well suited for tasks that require high accuracy over a period of time, such as time-series forecasting, because they can retain long-term dependencies in memory. Extreme Learning Machines (ELMs) and Echo State Networks (ESNs) suitable for real-time or lower-resource environments (efficiency), because they are faster to train and require less computational power for inference; however, they are less precise than other algorithms. Convolutional Neural Networks (CNNs) are well suited for image classification tasks and large datasets, due to their ability to learn patterns making them robust and highly scalable algorithms. Thus, when selecting an AI algorithm for an application, it is essential to understand the strengths and weaknesses of the algorithm, as well as how well it meets the specific needs of the application. For example, if I have to choose a method, CNNs are well suited for image analysis applications such as detecting tumors from MRI scans; because they can learn and extract patterns from images. However, when trained, they require large datasets and significant computational resources when inferencing. Therefore, when using CNNs for this application, it is important to ensure that the application has access to sufficient data and computational power. References: Baheti, P. (2024, July 2). The Essential Guide to Neural Network architectures. V7. https://www.v7labs.com/blog/neural-network-architectures-guide Baluja, H. (2024, October 7). The Complete Guide to AI Algorithms. Hubspot. https://blog.hubspot.com/marketing/ai-algorithms Biswal, A. (2024, July 16). Top 10 Deep Learning Algorithms You Should Know in 2024. Simplilearn.com . https://www.simplilearn.com/tutorials/deep-learning-tutorial/deep-learning-algorithm Boesch, G. (2024, August 19). Deep Neural Network: The 3 Popular Types (MLP, CNN and RNN). viso.ai . https://viso.ai/deep-learning/deep-neural-network-three-popular-types/ Complexica (n.d.). Optimization Algorithms. Complexica Glossary. https://www.complexica.com/narrow-ai-glossary/optimization-algorithms Gupta, M. (2024, October 16). Supervised machine learning. GeeksforGeeks. https://www.geeksforgeeks.org/supervised-machine-learning/ Javatpoint (n.d.). Unsupervised Machine learning. Javatpoint. www.javatpoint.com . https://www.javatpoint.com/unsupervised-machine-learning Kerner, S. M. (2024, October 16). Types of AI algorithms and how they work. Enterprise AI. https://www.techtarget.com/searchenterpriseai/tip/Types-of-AI-algorithms-and-how-they-work Tavasoli, S. (2024, October 10). 10 Types of Machine Learning Algorithms and Models. Simplilearn.com . https://www.simplilearn.com/10-algorithms-machine-learning-engineers-need-to-know-article Liu, C.-H, Chang, C.-W.,& Lee, H.-W. (2018). A review of artificial intelligence algorithms used for smart machine tools. In Prof. Dr. Chien-Hung Liu (Ed.), Inventions [Journal-article]. https://doi.org/10.3390/inventions3030041 Microsoft (n.d.). The difference between AI and machine learning. Microsoft Azure. https://azure.microsoft.com/en-us/resources/cloud-computing-dictionary/artificial-intelligence-vs-machine-learning Murel, J., & Kavlakoglu, E. (2024, August 30). Reinforcement Learning. What is reinforcement learning? IBM. https://www.ibm.com/topics/reinforcement-learning Network of the National Library of Medicine (n.d.). Neural Networks. NNLM. https://www.nnlm.gov/guides/data-glossary/neural-networks Tableau (n.d.). Artificial intelligence (AI) algorithms: a complete overview. Salesforce. https://www.tableau.com/data-insights/ai/algorithms Vargas, R., Jiang, N., & Sircar, S. (2023, December 1). What makes AI algorithms different from traditional computer algorithms? https://www.linkedin.com/advice/3/what-makes-ai-algorithms-different-from-omp7f Visha (2023, May 29). Probabilistic Models in Machine Learning. GeeksforGeeks. https://www.geeksforgeeks.org/probabilistic-models-in-machine-learning/
- Pointers in C++: Memory Management, Arrays, and Smart Pointers
This article explores the role of pointers in C++, their role in memory management, how they interact with arrays, how to utilize pointer arithmetic, and differ from arrays in handling memory allocation and access. It also highlights the use of smart pointers like unique_ptr for safer memory handling, reducing risks associated with raw pointers. Alexander S. Ricciardi October 24, 2024 The C++ programming language provides memory management through pointers. Pointers offer flexibility and precise control over memory, making them a powerful tool for applications where memory usage management and manipulation are needed. This post discusses how pointers interact with arrays, whether arrays are necessary when using pointers, how pointer arithmetic relates to arrays and the differences between the address-of operator (&) and the dereference operator (*). Additionally, the post refers to Unique pointers. Pointers and Arrays: How They Work Together In C++, pointers and arrays work well together, but arrays are not necessarily required when using pointers and vice versa. However, they are often used together due to their similar nature, as they use direct memory access; that is arrays use indexing to access elements, while pointers use memory addresses to access elements. Both are derived data types in C++ that have a lot in common (Rinkalktailor, 2024); a derived data type is a data type that is created or derived from the fundamental or built-in data types. In some cases, pointers can even replace arrays. However, if they are very closely related they are still different data types. Below is a table listing the similarities and differences between the two data types. Table 1 Arrays vs Pointers Note: From “Pointers vs Array in C++” by Rinkalktailor (2024), modify. As mentioned earlier arrays are not strictly necessary when using pointers, and vice versa. Below are three examples that illustrate the interaction between arrays and pointers, pointer arithmetic, and how pointers can be used to access array elements, as well as an example of how to use a pointer as an array. Example 1: Accessing Array Elements Using Indexing int arr[5] = {1, 2, 3, 4, 5}; for (int i = 0; i < 5; ++i) { std::cout << arr[i] << " "; // Uses a variable as an index to access // element in the array } // Outputs 1 2 3 4 5 This is the typical method used to access elements in arrays. Example 2: Accessing Array Elements Using Pointer Arithmetic int arr[5] = {1, 2, 3, 4, 5}; int *ptr = arr; // arr acts like a pointer to the first element for (int i = 0; i < 5; ++i) { std::cout << *(ptr + i) << " "; // Dereferencing the pointer to access array // elements } // Outputs 1 2 3 4 5 This method uses pointer arithmetic ‘(*(ptr + i)) ’ to access the element in the array. Pointer arithmetic allows incrementing (++) and decrementing (--) pointers, or adding/subtracting integers to pointers to access elements in the array (Yashk, 2023). See this post section on Pointer Arithmetic for more information. In essence, in this example, the pointer is used as an array. Example 3: Pointer Arithmetic to Traverse an Array int arr[5] = {1, 2, 3, 4, 5}; int *ptr = arr; std::cout << *ptr << " "; // Outputs 1 ptr++; std::cout << *ptr << " "; // Outputs 2 ptr += 2; std::cout << *ptr << " "; // Outputs 4 This example is similar to the previous one, it also used the pointer is used as an array and pointer arithmetic. Note that, the code line ‘i nt *ptr = arr; ’ the pointer ‘ ptr ’ points to the first element of the array. In C++, when assigning an array to a pointer, the pointer points to the first element of that array. Pointers and arrays in C++ work well together. While similar, they diverge in how they handle memory allocation and how elements are accessed. Additionally, pointers can be directly manipulated using pointer arithmetic. Pointer Arithmetic In C++, pointer arithmetic is a powerful tool for memory management. "Pointer arithmetic refers to the operations that are valid to perform on pointers" (Sagar, 2024, p.1). Below is a list of valid pointer arithmetic operations: 1- Incrementing and Decrementing Pointers When a pointer is incremented ‘ptr++’, it points to the value of the derived data type which is in the next memory location. For instance, if ‘ ptr ’ is an ‘ int* ’, incrementing it moves it to the next integer in memory, which is typically 4 bytes ahead, as integers usually have a 4-byte size. Similarly, decrementing a pointer ‘ ptr-- ’ moves it to the previous element in memory. int arr[3] = {10, 20, 30}; int* ptr = arr; ptr++; // Now points to arr[1] (20) std::cout << *ptr << std::endl; // Outputs 20 ptr--; // Now points back to arr[0] (10) std::cout << *ptr << std::endl; // Outputs 10 2- Addition of Constant to Pointers For example, if adding the constant ‘ 2 ’ to a pointer, it will move forward the pointer by ‘ 2 * size of int bytes ’ int arr[5] = {10, 20, 30, 40, 50}; int* ptr = arr; ptr = ptr + 2; // Moves the pointer to arr[2] (30) std::cout << *ptr << std::endl; // Outputs 30 3- Subtraction of Constant from Pointers Similar to adding a constant to a pointer, For example, if subtracting constant ‘ 2 ’ to a pointer, it will move backward the pointer by ‘ 2 * size of int bytes ’ int arr[5] = {10, 20, 30, 40, 50}; int* ptr = &arr[4]; // Points to arr[4] (50) ptr = ptr - 3; // Moves back 3 elements, now pointing to arr[1] (20) std::cout << *ptr << std::endl; // Outputs 20 4- Subtraction of Two Pointers of the Same Type Subtracting of the same type will find the number of elements between them. For example: int arr[5] = {10, 20, 30, 40, 50}; int* ptr1 = &arr[1]; // Points to arr[1] (20) int* ptr2 = &arr[4]; // Points to arr[4] (50) int difference = ptr2 - ptr1; // Difference in elements std::cout << "Difference: " << difference << std::endl; // Outputs 3 5- Comparison of Pointers Tow pointers can be compared using relational operators ( >, <, >=, <=, ==, != ). This can tell if the two pointers are pointing to the same memory location or not. For example: int num1 = 10, num2 = 20; int* ptr1 = &num1; int* ptr2 = &num2; if (ptr1 != ptr2) { std::cout << "The pointers point to different locations." << std::endl; } else { std::cout << "The pointers point to the same location." << std::endl; } // The pointers point to different locations Pointer arithmetic is powerful for manipulating and comparing pointers and the value they point to. This is possible through the use of the address-of and dereference operators (*) and (&) as shown in the prior example. Address-of and Dereference Operators (*) and (&) Understanding how pointers handle addresses and value stores in those addresses is crucial for coding without generating errors. At the center of the pointer’s functionality are the address-of operator (&) and the indirection operator/Dereference operator (*). The diagram below shows the makeup of a pointer in C++. Figure 1 Pointer Note: From “C++ Pointer Operators” by Raj (2022). - The address-of operator (&) is a unary operator. It returns the memory address of the variable. For example: int x = 10; int *ptr = &x; // ptr now holds the address of x - The dereference operator (*) is a unary operator. It returns the value of the variable present at the given address.For example: std::cout << *ptr; // Outputs the value of x (10) *ptr = 20; // Modifies the value of x through the pointer std::cout << x; // Outputs the updated value of x (20) The address-of and dereference operators allow developers to manage and manipulate memory addresses and the value stored in them through the pointer functionality. However, pointers can create significant safety risks if used improperly, they can cause undefined behavior, crashes, or security vulnerabilities such as buffer overflows. A good practice is to use smart pointers, called unique pointers in C++, rather than raw pointers, to ensure safer memory management. Smart Pointers Smart pointers in C++ are also referred to as unique pointers (‘unique_ptr’). They automatically manage the dynamically allocated resources on the heap. They are just wrappers around regular raw pointers preventing errors such as forgetting to delete a pointer and causing a memory leak or accidentally deleting a pointer twice or in the wrong way (Pritamauddy, 2023). Additionally, a ‘unique_ptr’ does not share its raw pointer, meaning that it cannot be copied to another ‘unique_ptr’ (Whitney, 2021). Instead, it can only moved. This means that the ownership of the memory address of the values stored can be transferred from one ‘unique_ptr’ to another. For example: #include #include // std::unique_ptr #include // std::move int main() { std::unique_ptr ptr1 = std::make_unique(10); std::cout << "Value pointed by ptr1: " << *ptr1 << std::endl; // Moving ownership from ptr1 to ptr2 std::unique_ptr ptr2 = std::move(ptr1); // ptr1 is now empty if (!ptr1) { std::cout << "ptr1 is now empty."<< std::endl; } // ptr2 now owns the address std::cout << "Value pointed by ptr2: " << *ptr2 << std::endl; // No need to delete manually; unique_ptr automatically deletes the // resource when // it goes out of scope return 0; } As shown in the code example the ‘ unique_ptr ’ is safer to use than a raw pointer, it automatically manages access to the heap, protecting it from errors by wrapping around (managing) a raw pointer. To summarize, pointers offer flexibility and precise control over memory, making them a powerful tool for applications where memory usage management and manipulation are needed. Pointers and arrays work well together; arrays are not necessarily required when using pointers and vice versa. Nonetheless, they are similar as both are derived data types and use direct memory access. However, they handle memory allocation and how elements are accessed differently. Pointers and the values they point to can be manipulated using pointer arithmetic and the operators (*) and (&). This comes with risks that can be mitigated by using the smart pointers (‘ unique_ptr ’), which manage access to the heap, protecting it from errors. References: Pritamauddy (2023, October 5). Unique_ptr in C++. GeeksforGeeks. https://www.geeksforgeeks.org/unique_ptr-in-cpp/ Raj (2022, December 20). C++ Pointer operators. GeeksforGeeks. https://www.geeksforgeeks.org/cpp-pointer-operators/ Rinkalktailor (2024, May 15). Pointers vs array in C++. GeeksforGeeks. https://www.geeksforgeeks.org/pointers-vs-array-in-cpp/ Sagar (2024, May 1). C++ Pointer arithmetic. GeeksforGeeks. https://www.geeksforgeeks.org/cpp-pointer-arithmetic/?ref=oin_asr26 Whitney, T., Junshen, T., Sharkey, K., Voss, J., Jones, M., Blome, M., Hogenson, G., & Cai, S. (2021, November 12). How to: Create and use unique_ptr instances. Microsoft Learn. https://learn.microsoft.com/en-us/cpp/cpp/how-to-create-and-use-unique-ptr-instances?view=msvc-170&viewFallbackFrom=vs-2019 Yashk. (2023, January 16). C++ Program to access elements of an array using pointer. GeeksforGeeks. https://www.geeksforgeeks.org/cpp-program-to-access-elements-of-an-array-using-pointer/
- Inheritance and Polymorphism in Java: Using Superclasses and Subclasses
This article explains how Java’s inheritance has an “is-a” relationship between superclasses and subclasses, allowing subclasses to inherit and customize superclass functionality. By using polymorphism, subclasses can define unique behaviors, allowing code reuse and flexibility in object-oriented programming. Alexander S. Ricciardi June 10, 2024 In Java, the relationship between super-classes (parent class) and subclasses (child class or derived class) in inheritance is a is-a relationship implying that the subclass is a specialized version of the superclass inheriting the functionality (restrictions can be applied) of a class that it is derived from (CSU Global, n.d). In other words, if class B inherits from class A, then class B "is a" type of class A. This relationship allows class B to use all the functionalities (restrictions can be applied) provided by class A, while also adding its own specific functionalities or/and by overriding some or all of the functionalities of class A. The ability of the child class to override functionality is a form of polymorphism. “The dictionary definition of polymorphism refers to a principle in biology in which an organism or species can have many different forms or stages. This principle can also be applied to object-oriented programming and languages like the Java language. Subclasses of a class can define their own unique behaviors and yet share some of the same functionality of the parent class” (The Java™ Tutorials, n.d.)This is especially beneficial when dealing with multiple objects from different subclasses that share a common superclass type. For example: dogs, cats, and owls are animals: Superclass public class Animal { public void makeSound() { System.out.println("Makes a Sound"); } } Subclass of Animals public class Domesticated extends Animal { public void friendly() { System.out.println("This animal is friendly."); } } Subclass of Animals public class Undomesticated extends Animal { public void notFriendly() { System.out.println("This animal is not friendly."); }} Subclass of Domesticated public class Undomesticated extends Animal { public void notFriendly() { System.out.println("This animal is not friendly."); } } Subclass of Domesticated public class Cat extends Domesticated { @Override public void makeSound() { System.out.println("Meow"); } } Subclass of Undomesticated public class Owl extends Undomesticated { @Override public void makeSound() { System.out.println("Hoots"); } } Main class to output the result public class inheritanceExample { public static void main(String[] args) { Dog myDog = new Dog(); Cat myCat = new Cat(); Owl redOwl = new Owl(); System.out.println("MY Dog:"); myDog.makeSound(); // Outputs: Bark myDog.friendly(); // Outputs: This animal is friendly. System.out.println(); System.out.println("My Cat:"); myCat.makeSound(); // Outputs: Meow myCat.friendly(); // Outputs: This animal is friendly. System.out.println(); System.out.println("Red Owl:"); redOwl.makeSound(); // Outputs: Hoot redOwl.notFriendly(); // Outputs: This animal is not friendly. } } Note: The makeSound() methods in the Dog and Cat classes override the makeSound() method in the Animal class. Additionally, the Dog class is a subclass of the Domesticated class which is a subclass of the Animal class. Child of In Java, a subclass can only have one superclass, for example, the Dog class cannot have a superclass Domesticated and a superclass Animal , the following is not allowed. In other words, a subclass can have one parent class, one grandparent class, one great-grandparent class, … and they are not allowed to have multiple parents, grandparents, or great-grandparents. In conclusion, Java's inheritance allows subclasses to utilize and extend the functionality of superclasses, embodying the "is-a" relationship and facilitating polymorphism. This enhances code reusability, flexibility, and consistency by enabling specific behaviors in subclasses while maintaining shared characteristics across a common superclass. References: CUS Global (n.d.). Module 1: Working with inheritance [Interactive lecture]. In Colorado State University Global, CSC372: Programming II, Computer Science Department. Canvas. Retrieved June 8, 2024, from https://csuglobal.instructure.com/courses/94948/pages/module-1-overview?module_item_id=4868813 The Java™ Tutorials (n.d.). Learning the Java language: Interfaces and inheritance . Oracle. Retrieved June 8, 2024, fromhttps:// docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html
- Memory Management in Java: Java Virtual Machine
This article is an overview of memory management in Java. It explains key components of the Java Virtual Machine (JVM), including the stack, heap, and garbage collection. Alexander S. Ricciardi May 27, 2024 Memory management in Java is essential for various reasons. Java Virtual Machine (JVM) automates memory handling by utilizing stack, heap, and garbage collection system. This lightens the load on developers by taking care of memory allocation and deallocation. Nonetheless, developers can not overlook memory management entirely. See the definitions for JVM, stack, heap, and garbage collection at the end of the post. Below is a list of key reasons why understanding memory management is important: - Enhancing Performance. Effective memory management directly impacts your application's performance. Understanding how memory is managed empowers developers to generate efficient code that optimizes resource usage, ensuring applications operate seamlessly without unnecessary hitches or crashes. For example, being aware of the distinctions between stack and heap memory, along with how objects are assigned in each space, aids developers in optimizing the utilization of these memory regions (Marian, 2021). - Preventing Memory Leaks. Despite Java featuring a garbage collector, it doesn't ensure immediate elimination of unused objects. Mishandled memory can result in memory leaks where redundant objects linger in the system's memory, eventually leading to an application running out of available memory. This underscores the importance of comprehending reference mechanisms and recognizing when objects qualify for garbage collection (Gassner, 2020). - Addressing OutOfMemoryError.A solid grasp of memory management proves valuable when identifying and resolving issues related to insufficient system resources like OutOfMemoryError.This error occurs when the JVM runs out of memory, which can halt your application. Developers can prevent such errors proactively by learning how to oversee and control memory usage effectively (Gassner, 2020). - Optimizing Garbage Collection. Various garbage collection methods can be utilized depending on the requirements of the application. For instance, the Serial, Parallel and Garbage First (G1) garbage collectors each come with their own strengths and weaknesses. Understanding these options can assist developers in configuring their JVM to utilize the most suitable garbage collector for their specific application needs, thereby improving performance and responsiveness (Marian, 2021). - Scalability Considerations.Efficient management of memory plays a crucial role in scaling applications. As applications expand to accommodate more data and users, efficient memory utilization ensures smooth scalability without encountering performance bottlenecks or memory related challenges. This involves comprehending how to handle object lifecycles effectively and optimizing data structures for minimal memory consumption (Marian, 2021). In summary, although Java offers automatic memory management capabilities, a thorough understanding of its mechanisms empowers developers to create more efficient, resilient and scalable applications. Adapting proper memory management practices would guarantee optimal performance, prevents memory leaks, addresses errors proficiently and facilitates seamless scalability for applications. Definitions: - Java Virtual Machine: Or JVM, loads, verifies, and runs Java bytecode. It is known as the interpreter or the core of the Java programming language because it runs Java programming.The role of JVM in JavaJVM is responsible for converting bytecode to machine-specific code and is necessary in both JDK and JRE. It is also platform-dependent and performs many functions, including memory management and security. In addition, JVM can run programs that are written in other programming languages that have been converted to Java bytecode (IBM, 2030). - StackThe stack: It is a component of Java's memory management system, it is used for storing local variables and method call information. Each thread in a Java application has its own stack, it is a memory structure used for managing method execution and local data within a thread. JVM manages it to access and clean up memory (the Heap) (Greencroft, 2018a). - HeapThe heap is a large memory area dedicated to storing objects in a Java application. Unlike the stack, which is used for local primitive variables and method call information, the heap's primary role is to hold data that persists beyond a single block of code or function call. This allows objects to be accessed and manipulated across different methods and threads within an application (Greencroft, 2018b). - Garbage collection: It is a form of automatic memory management, whose main function is deallocating memory space. It is part of the JVM memory management system. Unlike C or C++, where developers must manually allocate and deallocate memory, Java handles this automatically, ensuring that objects no longer in use are properly disposed of to free up memory resources (Gassner, 2020). References: Gassner, D. (2020, September 30). Memory management and garbage [Video]. Java 8 essential training. LinkedIn Learning. https://www.linkedin.com/learning/java-8-essential-training/memory-management-and-garbage-collection?autoAdvance=false&u=2245842/ Greencroft, M. (2018a, December 19). The role of the stack [Video]. Java memory management. LinkedIn Learning. https://www.linkedin.com/learning/java-memory-management/the-role-of-the-stack?autoAdvance=false&u=2245842/ Greencroft, M. (2018b, December 19). The role of the heap [Video]. Java memory management. LinkedIn Learning. https://www.linkedin.com/learning/java-memory-management/the-role-of-the-stack?autoAdvance=false&u=2245842 IBM (2021, June 30). JVM versus JRE versus JDK: What’s the difference? IBM. Retrieved from https://www.ibm.com/think/topics/jvm-vs-jre-vs-jdk Marian, C. (2021, February 19). Java memory management . DZone. https://dzone.com/articles/java-memory-management
- Bot Evolution and the Future of AI: Opportunities and Challenges
The article explores the development of bots from early automated systems to advanced AI agents, highlighting both their potential and limitations. It also discusses the future of AI, emphasizing the need to address societal inequalities as AI technology advances. Alexander S. Ricciardi October 15, 2024 Bots have been used to communicate with humans for a few decades, starting as early as the 1980s with Interactive Voice Response (IVR) systems. These systems are typically used to answer customer calls, like those used by banks where you say "yes" or "representative" to be automatically connected (Pawlewicz, n.d.). They have also been used to communicate with sensors or data. LabBot is an excellent example; it uses a Telegram bot that can be programmed to monitor sensor data and send automatic warning messages when the sensor exceeds limits (Alexriss, n.d.). A Telegram bot uses the Telegram messaging service app., to communicate with users allowing users to send commands and receive information, such as sensor readings or control outputs from devices (Victor, 2020). However, one of the most fascinating bot interactions is when bots interact with each other. The article "Even Good Bots Fight: The Case of Wikipedia" by Tsvetkova et al. (2017) is a study that analyzes the interactions between Wikipedia bots between 2001 and 2010. Most Wikipedia bots are designed to edit and link Wikipedia articles, the study found that the bots often end up undoing each other's edits, sometimes leading to prolonged editing conflict between bots. What is a Bot? A bot is a program or a collection of programs that performs automated tasks usually over the Internet. In the context of the Wikipedia encyclopedia, bots are owned by Wikipedia editors and can perform a wide range of tasks, from fixing broken links and categorizing pages to undoing acts of vandalism (Kohli, 2018). They can be considered a form of Narrow AI. Narrow AIs are systems designed to perform specific tasks and operate under limited constraints (Awan, 2023). Wikipedia Bots Interactions Wikipedia Bots are programmed to perform specific tasks like editing, linking pages, or correcting errors (Kohli, 2018). Bots, in some cases, make over 50% of the edits in smaller Wikipedia language editions (Tsvetkova et al., 2017). This editing task and maintaining datasets, notably large datasets would be overwhelming for humans alone. Thus, the bots play a crucial role in maintaining and keeping the encyclopedia up-to-date and relevant. However, during the period from 2001 to 2010, Wikipedia bots were known to undo each other's edits repeatedly and could be described as "bot wars" or bots editing wars (Godosh, 2017). These editing war-like conflicts, in some cases, went on for years wasting time and resources. This occurred because the bots were following slightly different editing rules or interpretations of how to edit articles and were not programmed to collaborate. Moreover, this highlights the challenges involved in creating logical agents that follow a rigid set of rules. Logical agents are AI agents that act based on a Knowledge Base (KB) (and a set of rules) to infer (to derive) new knowledge or make decisions accordingly (Russell & Norvig), in the case of the Wikipedia bots to or not to edit or undo edits. In other words, Wikipedia bots reflect the shortcomings of Narrow AIs which have narrow KB, lack flexibility, and are missing contextual understanding needed for deep communication and collaboration. The Future of Bots However, with the emergence of Large Language Models based on the Transformers neural network architecture such as ChatGPT and Claude, bots can be transformed into AI agents capable of autonomy performing more than just one narrow task but a multitude of tasks, capable of communicating, collaborating, delegating, and even hiring other AI Agents and humans to perform task for them. According to an Accenture Report (2024, p. 73), “96% of executives agree that leveraging AI agent ecosystems will be a significant opportunity for their organizations in the next three years.” Fully agentic AI is predicted to appear on mobile devices and PCs as early as 2025. This will fundamentally transform how people from the modern industrialized society learn, work, communicate, and live their daily lives, as well as impact the rest of humanity, hopefully for the better… What I would like to see implemented. I would like to talk to my computer and ask it to perform tasks for me, such as opening a file for me while I am writing a paper in a different file or coding. In other words, I want an AI Agentic Operating System for PCs capable of interfacing through voice, vision, and text; including mouse, keyboard, and touch screens. This would allow me to multitask more efficiently, making my life much easier. On a more serious note, the 2024 Nobel Prize in Physics went to J. Hopfield and G. Hinton for machine learning discoveries. Hilton also called the godfather of AI, said “I am worried that the overall consequence of this might be systems more intelligent than us that eventually take control" (Pollard & Ashlander, 2024, p1). Hinton's concerns are grounded and very real. However, my main concern, not to dismiss Hilton's concern, is that AI will generate a greater gap between industrialized countries and developing nations exacerbating existing inequalities; and in the long run, creating a speciation situation of the human race (e.g. augmented and none-augmented human)—Between those that can afford human augmentations brought through AI and technologies such as Crisper , Anti-Aging , and Neuralink and those that can't. Thus, what I really would like to see is the implementation of AI that benefits not just a select few, but humanity as a whole. To summarize, bots have evolved from simple automated systems to sophisticated AI. The future promises more AI agentic systems capable of autonomously handling complex, multi-task operations, potentially transforming how we work and live, with technological and scientific advancements that would seem magical. It is up to us to ensure these advancements are used for the good of all humanity. References: Accenture Report (2024, January 9). Technology Vision 2024: Human by design [PDF-Slides]. Accenture. https://www.accenture.com/content/dam/accenture/final/accenture-com/document-2/Accenture-Tech-Vision-2024.pdf#zoom=40 Alexriss, (n.d.). LabBot. Github. https://github.com/alexriss/labbotLinks to an external site. Awan, A. (2023, June 2023). What is narrow AI? Datacamp. https://www.datacamp.com/blog/what-is-narrow-ai/ Godosh, S. (2017, February 27). Wikipedia bots spent years fighting silent, tiny battles with each other . Popular Science. https://www.popsci.com/wikipedia-bots-fighting/ Kohli, N. (2018, October 16). The bots that help run Wikipedia [Video]. Strange Loop Conference – YouTube. https://www.youtube.com/watch?v=mOmLiAPdF0Y&t=50s Pawlewicz, K. (n.d.) A history of customer service. Olark. https://blog.olark.com/the-history-of-customer-service/ Pollard, N., & Ahlander, P. (2024, October 2024). Nobel physics prize 2024 won by AI pioneers John Hopfield and Geoffrey Hinton. Reuter. https://www.reuters.com/science/hopfield-hinton-win-2024-nobel-prize-physics-2024-10-08/ Tsvetkova, M., García-Gavilanes, R., Floridi, L., & Yasseri, T. (2017). Even good bots fight: The case of Wikipedia . PLoS One, 12 (2). Russell, S. & Norvig, P. (2021). 7. Logical Agent. Artificial intelligence: A modern approach. 4th edition . Pearson Education, Inc. ISBN: 9780134610993; eISBN: 9780134671932. Victor (2020, July 9). Telegram: Request ESP32/ESP8266 sensor readings (Arduino IDE) . Random Nerd Tutorials. https://randomnerdtutorials.com/telegram-request-esp32-esp8266-nodemcu-sensor-readings/
- Common String Manipulation Errors in C++ and How to Avoid Them
This article highlights common string manipulation errors in C++, such as buffer overflows, null terminators, and invalid iterator usage, which can lead to serious security vulnerabilities. It offers solutions and best practices based on the SEI CERT C++ Coding Standards to help developers write secure and reliable code when working with strings. Alexander S. Ricciardi October 16, 2024 In software development, working with strings is notoriously error-prone and can generate security vulnerabilities, especially in C++. C++ is a flexible programming language that allows manual memory management and when combined with the primitive nature of strings, it is very easy for developers to accidentally introduce errors and dangerous vulnerabilities when manipulating strings. Below is a list of common string-manipulating errors: - Buffer Overflows: One of the most common errors leading to significant security vulnerabilities. This happened usually when copying data to a buffer that is not large enough to hold that data (Ballman, 2016), especially when functions such as ‘ strcpy() ’, which does not check the length of the destination when coping an array of characters. A solution is to use functions like ‘strncpy()’, which limit the number of characters copied; however using ‘sdt::string’ is often a better solution as it is dynamic length, meaning is not a bounded array and it is no need to manage the null terminators ‘\0’. Making sure that a destination string buffer is compliant with the length of the string stored is compliant with the SEI CERT C++ CODING STANDARD STR50-CPP “ Guarantee that storage for strings has sufficient space for character data and the null terminator ” (SEI External WIKI, n.d., STR50-CPP). See the code examples below: // Example 1: Buffer Overflow (STR50-CPP) void bufferOverflowExample() { char buf[12]; // Error: Buffer overflow if the input is longer than 12 characters std::cin >> buf; // Solution: Use std::string instead } void bufferOverflowSolution() { std::string input; std::cin >> input; // Using std::string avoids overflow } - Null-Terminator: When C-style strings are used ‘char[ ]’ not allocating the null-terminator ‘\0’ at the end of the character array may result in undefined behavior and memory corruption, as well as creating vulgarities. Without a null terminator, functions may read out-of-bounds memory and can be exploited for nefarious purposes. Thus, always add ‘\0’, if the string is 9 characters long the character array should have a length of 10 to accommodate ‘\0’ at the end of it. This is part of STR50-CPP. See the code examples below: // Example 2: Null-Terminator Issue (STR50-CPP) void nullTerminatorIssue() { char buf[12] = {'p', 'a', 'n', 'd', 'a', 's'}; // Missing null terminator std::cout << buf << std::endl; // Undefined behavior } void nullTerminatorSolution() { char buf[10] = {'p', 'a', 'n', 'd', 'a', 's', '\0'}; // Add null terminator explicitly std::cout << buf << std::endl; } - Unbounded String Input: When C-style strings are used ‘char[]’, always limits the input size, that is when using ‘std::cin’ to the length of the character array receiving the inputs to the length of the array – 1 (to accommodate ‘\0’). Failing to do so may cause data overflows. This part of STR50-CPP. See the code examples below: // Example 3: Unbounded Input (STR50-CPP) void unboundedInputIssue() { char buf[10]; std::cin >> buf; // No limit on input size, may cause overflow } void boundedInputSolution() { char buf[10]; std::cin.width(10); std::cin >> buf; // Limits input to 9 characters } - Strings Null Pointers: Do not create a ‘std::string’ from a null pointer, for example, using ‘std::getenv()’, that is getting an environment variable without checking if the variable exists, this may result in a null pointer if the environment variable does not exists. Allocating the value of a null pointer to a ‘std::string’ may lead to undefined behavior and dereferencing a null pointer, that is trying to access an invalid memory address. Making sure that a ‘std::string’ is not created from a null pointer is compliant with the SEI CERT C++ CODING STANDARD STR51-CPP “ Do not attempt to create a std::string from a null pointer ” (SEI External WIKI, n.d., STR51-CPP). See the code examples below: // Example 4: Null Pointer with std::string (STR51-CPP) void nullPointerStringIssue() { const char *envVar = std::getenv("LINK_TO_NOWHERE"); std::string str(envVar); // Undefined behavior if envVar is nullptr } void nullPointerStringSolution() { const char *envVar = std::getenv("LINK_TO_NOWHERE"); std::string str(envVar ? envVar : ""); // Handles nullptr } - String Invalid Iterator Usage: Making sure that a string iterator is still valid after modifying a string is crucial as it can result in the iterator not reflecting changes to the string properly. This often occurs when using the ‘insert()’ or ‘replace()’ methods. Thus, revalidating the iterator by relocating the value of the string after each string modification is essential. Making sure that the string iterator is still valid after modifying a string is compliant with the SEI CERT C++ CODING STANDARD STR52-CPP “ Use valid references, pointers, and iterators to reference elements of a basic_string ” (SEI External WIKI, n.d., STR52-CPP). See the code examples below // Example 5: Invalid Iterator Usage (STR52-CPP) void invalidIteratorIssue() { std::string input = "example"; std::string::iterator it = input.begin(); input.insert(it, 'E'); // Insert invalidates iterators ++it; // Undefined behavior - iterator has been invalidated } void validIteratorSolution() { std::string input = "example"; std::string::iterator it = input.begin(); it = input.insert(it, 'E'); // Update iterator ++it; } - String Unchecked Range Access: Do not access elements outside the valid range of a string, this often occurs when using functions like ‘front()’ and ‘back()’, this can lead to undefined behavior. Thus, always perform range checks before trying to access an element, or use safer functions like ‘at()’ that throw exceptions on out-of-range access. Not accessing elements outside the valid range of a string is compliant with the SEI CERT C++ CODING STANDARD STR53-CPP “ Range check element access ” (SEI External WIKI, n.d., STR53-CPP). See the code examples below: // Example 6: Bounds Checking with std::string (STR53-CPP) void boundsCheckingIssue() { std::string s = "example"; char c = s[10]; // Undefined behavior if index is out of bounds } void boundsCheckingSolution() { std::string s = "example"; try { char c = s.at (10); // Throws std::out_of_range if index is out of bounds } catch (const std::out_of_range &e) { std::cerr << "Out of range error: " << e.what() << std::endl; } } The table below shows a summary of the risk assessment of the C++ string-related coding rules from the SEI CERT C++ Coding Standard. Table 1 String Rules Risk Assessment Note: From “Rule 05. Characters and Strings (STR). SEI CERT C++ Coding Standard ” by SEI External WIKI. (n.d.) Table Description: Rule(s) are the rules from rules from the SEI CERT C++ Coding Standard. Severity refers to the potential impact on security. Likelihood refers to how likely it is that violating the rule will result in a security vulnerability. Remediation Cost refers to the amount of effort needed to fix the violation. Priority (P) refers to the priority level at which a violation should be addressed, the lower the numbers the higher the priority. Level refers to the level of enforcement, that is how strictly the coding standard needs to be followed to not introduce vulnerabilities. To summarize, working with strings is notoriously error-prone and may cause security vulnerabilities, especially in C++. C++ is a flexible programming language that allows manual memory management, which increases the risk of introducing errors and vulnerabilities. However, by following the SEI CERT C++ Coding Standards, C++ developers can generate secure and reliable code when manipulating strings. References: SEI External WIKI. (n.d.) Rule 05. Characters and Strings (STR). SEI CERT C++ coding standard . Carnegie Mellon University. Software Engineering Institude. https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=88046330/ Ballman, A. (2016). Chapter-6 Characters and Strings (STR). SEI CERT C++ coding standard: Rules for developing safe, reliable, and secure systems in C++ . Software Engineering Institute (Carnegie Mellon University). Hanscom, MA.
- Designing User-Defined Methods in Java: Key Criteria
This post explores the criteria for designing user-defined methods in Java, focusing on functionality, reusability, maintainability, and clarity. It provides an example of a discount calculator method, illustrating how thoughtful design can address specific business needs while promoting efficient and maintainable code. Alexander S. Ricciardi May 20, 2024 Java, like other Object-Oriented Programming (OOP) languages, allows user-defined methods (functions) which provide developers with the flexibility to create methods that address the specific needs of an application. When designing a method, it is crucial to carefully consider the rationale, limitations, and criteria specific to each application while ensuring functionality, reusability, maintainability, and clarity. An example of a user-defined function/method that can be used to elaborate on the criteria utilized to develop the method and its rationale could be a method that calculates the discount for a customer based on loyalty points, seasonal promotions, and purchase history. Here are four criteria and rationales that I think should be used to develop the method: Define the task – Method functionality: If the task involves unique business logic or specific requirements that cannot be addressed by Java predefined methods, a user-defined method is necessary. In the case of the method described above, its task is to calculate the discount for a customer based on loyalty points, seasonal promotions, and purchase history. Rationale: Unique business logic and specific requirements often are required to develop appropriate solutions to a need or a problem that predefined methods cannot offer. User-defined function/method ensures that the solution meets the business needs. Task reusability – The method will be reused throughout the codebase: The task functionality will be reused in multiple parts of the application. The method can be called across different modules without duplicating code. Rationale: Reusability promotes modularity and reduces code duplication, ensuring consistent implementation of the discount calculation logic throughout the application. Future modifications – Method maintainability: Over time, the task’s functionality may need to change; for example, the number of loyalty points required to affect the discount calculation may vary in the future. The methods improve maintainability by encapsulating specific logic in one block of code. This makes it easier to update/change and debug the code. Rationale: Encapsulation of code logic and functionality within a method makes maintainability possible and easier. This makes future updates or modifications simpler and reduces the risk of introducing errors. Task describing – Naming, parameters, Javadocs, and comments: Documentation is needed to describe the task and define the task parameters. Naming a method appropriately, choosing/declaring clear parameters, and using Javadocs and comments are crucial for code readability/understandability and defining parameters. Rationale: Well-documented code with clear naming conventions and parameter declaration and improves code functionality, readability, and helps other developers understand the purpose and functionality of the method. Code Example: /** * The DiscountCalculator class provides functionality to calculate discounts * for customers based on loyalty points, seasonal promotions, and purchase history. */ public class DiscountCalculator { /** * Calculates the discount for a customer based on loyalty points, * seasonal promotions, and purchase history. * * @param loyaltyPoints (int) The number of loyalty points. * @param seasonalPromo (Double) The seasonal promotion discount percentage. * @param purchaseHistory (double) The customer's total purchase history amount. * @return (double) The calculated discount amount. */ public double calculateDiscount(int loyaltyPoints, double seasonalPromo, double purchaseHistory) { double baseDiscount = 0.0; // Add loyalty points discount baseDiscount += loyaltyPoints * 0.01; // Apply seasonal promotion baseDiscount += seasonalPromo; // Additional discount based on purchase history if (purchaseHistory > 1000) { baseDiscount += 5.0; // Additional 5% discount for high spenders } return baseDiscount; } } It is also important to understand when designing the method vocabulary specific to each programming language, below is Java method vocabulary: Figure 1 Java Method Vocabulary Note: From " Introduction to Programming with Java: 5.1.1 Writing Static Methods" by Ericson et al., 2015 To summarize, user-defined methods, such as the discount calculator, demonstrate the importance of balancing functionality, modularity, maintainability, and documentation in software design while carefully considering the rationale, limitations, and criteria specific to each application. By defining specific tasks, promoting reusability, planning for future modifications, and ensuring clear naming and documentation, developers can create methods that are not only effective but also adaptable to changing requirements. References: Ericson, B. (2015). Introduction to programming with Java: 5.1.1 Writing static methods [Image]. Runestone Academy. https://runestone.academy/ns/books/published/csjava/Unit5-Writing-Methods/topic-5-1-writing-methods.html
- Arrays in Java: Characteristics, Usage, and Real-Life Scenarios
This article explores the characteristics of arrays in Java, such as their fixed size, efficient access, and type safety, while comparing them to dynamic collection types like ArrayList. It also provides real-life scenarios, such as storing product quantities, modifying daily temperatures, and sorting student grades, to demonstrate practical applications of arrays in Java. Alexander S. Ricciardi May 14, 2024 In Java, arrays are a fundamental data structure that allows developers to store multiple values of the same type in a single variable. Arrays provide an efficient way to manage and manipulate data due to their fixed size and direct access capabilities. This article will explore the characteristics of Java arrays, compare them to other collection types like ArrayList, and present real-life scenarios where arrays are useful. Understanding the properties and applications of arrays is essential for building efficient Java programs. Below is a list of arrays characteristics in Java: Fixed Size : Once defined, the size of an array cannot be changed. Ordered : Arrays store elements in a sequential order which means that elements can be accessed by their index in constant time. Efficiency : Accessing any element in an array is a constant time operation. Arrays have a very low memory overhead because they store a single type of data. Single Type : Java arrays are typed, which means they can only store elements of the same data type as declared in the array declaration. Arrays are different from ArrayList, which are lists and are part of the Collection Interface. An Interface in Java is a reference type, similar to a class, that can contain only constants, default methods, static methods, and nested types (Tutorials Point, n. d.). In the case of the Collection Interface, it includes methods like add(), remove(), get(), and size(), among others (Oracle Doc., n.d.). This allows different types of list classes, such as ArrayList, LinkedList, and others like the Set class, to use those methods. Note that arrays are not part of the Collection Interface . In other words, they do not have methods associated with them. Real-Life Scenarios for Using Arrays Scenario 1: Store Product Quantities in a Store An array can be used to keep track of the quantities of different products in a store. For example, each element of the array represents the quantity of a specific product. public class Main { public static void main(String[] args) { // Stores product quantities int[] quantities = new int[4]; // Storing product quantities quantities[0] = 50; quantities[1] = 30; quantities[2] = 20; quantities[3] = 40; // Prints the product quantities for (int i = 0; i < quantities.length; i++) { System.out.println("Product " + (i + 1) + " Quantity: " + quantities[i]); } } } Outputs: Product 1 Quantity: 50 Product 2 Quantity: 30 Product 3 Quantity: 20 Product 4 Quantity: 40 Scenario-2: An array can be used to store and modify daily temperatures. public class Main { public static void main(String[] args) { // Stores daily temperatures int[] temperatures = {68, 70, 75, 72, 69, 71, 73}; // Prints initial temperatures System.out.println("Initial daily temperatures:"); printTemperatures(temperatures); // Modifies temperatures modifyTemperature(temperatures, 2, 78); modifyTemperature(temperatures, 5, 74); // Prints updated temperatures System.out.println("\nUpdated daily temperatures:"); printTemperatures(temperatures); } // Method to print all temperatures public static void printTemperatures(int[] temperatures) { String[] days = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday","Saturday", "Sunday"}; for (int i = 0; i < temperatures.length; i++) { System.out.println(days[i] + ": " + temperatures[i] + "°F"); } } // Method to modify a temperature public static void modifyTemperature(int[] temperatures, int dayIndex, int newTemperature) { if (dayIndex >= 0 && dayIndex < temperatures.length) { temperatures[dayIndex] = newTemperature; } else { System.out.println("Invalid day index!"); } } } Outputs: Initial daily temperatures: Monday: 68°F Tuesday: 70°F Wednesday: 75°F Thursday: 72°F Friday: 69°F Saturday: 71°F Sunday: 73°F Updated daily temperatures: Monday: 68°F Tuesday: 70°F Wednesday: 78°F Thursday: 72°F Friday: 69°F Saturday: 74°F Sunday: 73°F Scenario-3: An array can be used to store and sort students’ grades in a particular class. import java.util.Arrays; public class Main{ public static void main(String[] args) { // Two-dimensional array to store student IDs and their grades int[][] studentGrades = { {1, 85}, // {Student ID, Grade} {2, 90}, {3, 78}, {4, 92}, {5, 88} }; // Prints initial student grades System.out.println("Initial student grades:"); printAllGrades(studentGrades); // Sorting grades from lowest to highest sortGrades(studentGrades); // Printing sorted student grades System.out.println("\nSorted student grades:"); printAllGrades(studentGrades); } // Prints all grades public static void printAllGrades(int[][] studentGrades) { for (int i = 0; i < studentGrades.length; i++) { System.out.println("Student ID " + studentGrades[i][0] + ": " + studentGrades[i][1]); } } // Sorts grades public static void sortGrades(int[][] studentGrades) { Arrays.sort(studentGrades, (a, b) -> Integer.compare(a[1], b[1])); } } Outputs: Initial student grades: Student ID 1: 85 Student ID 2: 90 Student ID 3: 78 Student ID 4: 92 Student ID 5: 88 Sorted student grades: Student ID 3: 78 Student ID 1: 85 Student ID 5: 88 Student ID 2: 90 Student ID 4: 92 To summarize, Java arrays have a fixed size, they store multiple values of the same type. They offer efficient, constant access to elements by using indexes, making them suitable for scenarios where memory overhead and speed are a concern. While arrays do not provide the flexibility of collections like ArrayList, they still are an invaluable part of Java's toolkit for handling ordered data efficiently. References: Oracle Doc. (n.d.). Collection (Java SE 21) [Java Platform, Standard Edition Java API Specification]. Oracle. Retrieved from https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Collection.html / Tutorials Point. (n.d.). Java interfaces . Tutorials Point. Retrieved from https://www.tutorialspoint.com/java/java_interfaces.htm













