Survey | Started | Completed | Completion rate | Views |
---|---|---|---|---|
2023 | 11 950 | 9 710 | 82.2% | 16 028 |
2024 | 9 450 | 7 310 | 77.4% | 13 564 |
Closed answers marked with N/A were not present in the previous version(s) of the survey.
As you can see in the wordcloud, there are also a few users that prefer Arch, btw.
You can also take a look at the linked wordcloud that summarizes open answers to this question (the "Other" category), to see what other editors are also popular.
You can scroll the chart to the right to see more domains. Note that the Automotive domain was not offered as a closed answer in the 2023 survey (it was merely entered through open answers), which might explain the large jump.
|
https://ark.cn-beijing.volces.com/api/v3
,API key 就是你在火山引擎模型详情的"API 调用"里面,让系统生成的 API 密钥。ClassCastException
that was common while working with collection classes. The whole collection framework was re-written to use generics for type-safety. Let’s see how generics help us using collection classes safely.List list = new ArrayList();
list.add("abc");
list.add(new Integer(5)); //OK
for(Object obj : list){
//type casting leading to ClassCastException at runtime
String str=(String) obj;
}
Above code compiles fine but throws ClassCastException at runtime because we are trying to cast Object in the list to String whereas one of the element is of type Integer. After Java 5, we use collection classes like below.List<String> list1 = new ArrayList<String>(); // java 7 ? List<String> list1 = new ArrayList<>();
list1.add("abc");
//list1.add(new Integer(5)); //compiler error
for(String str : list1){
//no type casting needed, avoids ClassCastException
}
Notice that at the time of list creation, we have specified that the type of elements in the list will be String. So if we try to add any other type of object in the list, the program will throw compile-time error. Also notice that in for loop, we don’t need typecasting of the element in the list, hence removing the ClassCastException at runtime.package com.journaldev.generics;
public class GenericsTypeOld {
private Object t;
public Object get() {
return t;
}
public void set(Object t) {
this.t = t;
}
public static void main(String args[]){
GenericsTypeOld type = new GenericsTypeOld();
type.set("Pankaj");
String str = (String) type.get(); //type casting, error prone and can cause ClassCastException
}
}
Notice that while using this class, we have to use type casting and it can produce ClassCastException at runtime. Now we will use java generic class to rewrite the same class as shown below.package com.journaldev.generics;
public class GenericsType<T> {
private T t;
public T get(){
return this.t;
}
public void set(T t1){
this.t=t1;
}
public static void main(String args[]){
GenericsType<String> type = new GenericsType<>();
type.set("Pankaj"); //valid
GenericsType type1 = new GenericsType(); //raw type
type1.set("Pankaj"); //valid
type1.set(10); //valid and autoboxing support
}
}
Notice the use of GenericsType
class in the main method. We don’t need to do type-casting, and we can remove ClassCastException
error at runtime. If we don’t provide the type at the creation time, the compiler will warn that “GenericsType is a raw type. References to generic type GenericsType<T>
should be parameterized”. When we don’t provide the type, the type becomes Object
, and hence, it allows both String and Integer objects. But, we should always try to avoid this because we will have to use type casting while working on the raw type, which can produce runtime errors.@SuppressWarnings("rawtypes")
annotation to suppress the compiler warning, check out java annotations tutorial.package java.lang;
import java.util.*;
public interface Comparable<T> {
public int compareTo(T o);
}
In similar way, we can create generic interfaces in java. We can also have multiple type parameters as in Map interface. Again we can provide parameterized value to a parameterized type also, for example new HashMap<String, List<String>>();
is valid.package com.journaldev.generics;
public class GenericsMethods {
//Java Generic Method
public static <T> boolean isEqual(GenericsType<T> g1, GenericsType<T> g2){
return g1.get().equals(g2.get());
}
public static void main(String args[]){
GenericsType<String> g1 = new GenericsType<>();
g1.set("Pankaj");
GenericsType<String> g2 = new GenericsType<>();
g2.set("Pankaj");
boolean isEqual = GenericsMethods.<String>isEqual(g1, g2);
//above statement can be written simply as
isEqual = GenericsMethods.isEqual(g1, g2);
//This feature, known as type inference, allows you to invoke a generic method as an ordinary method, without specifying a type between angle brackets.
//Compiler will infer the type that is needed
}
}
Notice the isEqual method signature showing syntax to use generics type in methods. Also, notice how to use these methods in our java program. We can specify type while calling these methods or we can invoke them like a normal method. Java compiler is smart enough to determine the type of variable to be used, this facility is called type inference.public static <T extends Comparable<T>> int compare(T t1, T t2){
return t1.compareTo(t2);
}
The invocation of these methods is similar to unbounded method except that if we will try to use any class that is not Comparable, it will throw compile-time error. Bounded type parameters can be used with methods as well as classes and interfaces. Java Generics supports multiple bounds also, i.e <T extends A & B & C>. In this case, A can be an interface or class. If A is class then B and C should be an interface. We can’t have more than one class in multiple bounds.package com.journaldev.generics;
public class GenericsInheritance {
public static void main(String[] args) {
String str = "abc";
Object obj = new Object();
obj=str; // works because String is-a Object, inheritance in java
MyClass<String> myClass1 = new MyClass<String>();
MyClass<Object> myClass2 = new MyClass<Object>();
//myClass2=myClass1; // compilation error since MyClass<String> is not a MyClass<Object>
obj = myClass1; // MyClass<T> parent is Object
}
public static class MyClass<T>{}
}
We are not allowed to assign MyClass<String>
variable to MyClass<Object>
variable because they are not related, in fact MyClass<T>
parent is Object.ArrayList<E>
implements List<E>
that extends Collection<E>
, so ArrayList<String>
is a subtype of List<String>
and List<String>
is subtype of Collection<String>
. The subtyping relationship is preserved as long as we don’t change the type argument, below shows an example of multiple type parameters.interface MyList<E,T> extends List<E>{
}
The subtypes of List<String>
can be MyList<String,Object>
,MyList<String,Integer>
and so on.?
) is the wildcard in generics and represent an unknown type. The wildcard can be used as the type of a parameter, field, or local variable and sometimes as a return type. We can’t use wildcards while invoking a generic method or instantiating a generic class. In the following sections, we will learn about upper bounded wildcards, lower bounded wildcards, and wildcard capture.public static double sum(List<Number> list){
double sum = 0;
for(Number n : list){
sum += n.doubleValue();
}
return sum;
}
Now the problem with above implementation is that it won’t work with List of Integers or Doubles because we know that List<Integer>
and List<Double>
are not related, this is when an upper bounded wildcard is helpful. We use generics wildcard with extends keyword and the upper bound class or interface that will allow us to pass argument of upper bound or it’s subclasses types. The above implementation can be modified like the below program.package com.journaldev.generics;
import java.util.ArrayList;
import java.util.List;
public class GenericsWildcards {
public static void main(String[] args) {
List<Integer> ints = new ArrayList<>();
ints.add(3); ints.add(5); ints.add(10);
double sum = sum(ints);
System.out.println("Sum of ints="+sum);
}
public static double sum(List<? extends Number> list){
double sum = 0;
for(Number n : list){
sum += n.doubleValue();
}
return sum;
}
}
It’s similar like writing our code in terms of interface, in the above method we can use all the methods of upper bound class Number. Note that with upper bounded list, we are not allowed to add any object to the list except null. If we will try to add an element to the list inside the sum method, the program won’t compile.<? extends Object>
.public static void printData(List<?> list){
for(Object obj : list){
System.out.print(obj + "::");
}
}
We can provide List<String>
or List<Integer>
or any other type of Object list argument to the printData method. Similar to upper bound list, we are not allowed to add anything to the list.List<Integer>
but it will be tied up with Integers whereas List<Number>
and List<Object>
can also hold integers, so we can use a lower bound wildcard to achieve this. We use generics wildcard (?) with super keyword and lower bound class to achieve this. We can pass lower bound or any supertype of lower bound as an argument, in this case, java compiler allows to add lower bound object types to the list.public static void addIntegers(List<? super Integer> list){
list.add(new Integer(50));
}
List<? extends Integer> intList = new ArrayList<>();
List<? extends Number> numList = intList; // OK. List<? extends Integer> is a subtype of List<? extends Number>
public class Test<T extends Comparable<T>> {
private T data;
private Test<T> next;
public Test(T d, Test<T> n) {
this.data = d;
this.next = n;
}
public T getData() { return this.data; }
}
The Java compiler replaces the bounded type parameter T
with the first bound interface, Comparable, as below code:public class Test {
private Comparable data;
private Test next;
public Node(Comparable d, Test n) {
this.data = d;
this.next = n;
}
public Comparable getData() { return data; }
}
List list = new ArrayList(); // Avoid this
list.add("Hello");
list.add(123); // No type safety
Instead,use parameterized types instead:List<String> list = new ArrayList<>();
public void addItem(List<? extends Number> list) {
// list.add(10); // Compilation error
}
Instead, use ? super T
if modification is required:public void addItem(List<? super Integer> list) {
list.add(10);
}
class Box<T> {
private T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
Here, T
is a type parameter that can be replaced with any concrete type at runtime.public static <T> void printArray(T[] elements) {
for (T element : elements) {
System.out.println(element);
}
}
This method prints elements of an array of any type.List<?>
in Java Mean??
is a wildcard in Java generics. It represents an unknown type. For example:List<?> list = new ArrayList<String>();
This means the list can hold any type, but its exact type is unknown at compile time. You can learn more about comparators in java in this tutorial on Comparable and Comparator in Java Example.? extends T
: Represents an unknown type that is a subclass of T
. public void processElements(List<? extends Number> numbers) {
for (Number num : numbers) {
System.out.println(num);
}
}
? super T
: Represents an unknown type that is a superclass of T
.public void addNumbers(List<? super Integer> numbers) {
numbers.add(42);
}
ClassCastException
error. Instead, you can use a List<T>
:List<String> list = new ArrayList<>();
For more details on Java type annotations, refer to our tutorial on Java Annotations.class Box<T> {
// T obj = new T(); // Illegal
}
class Box<T> {
// static T instance; // Illegal
}
// List<int> list = new ArrayList<>(); // Illegal
List<Integer> list = new ArrayList<>();
lspci | grep—i nvidia
to identify your GPU. Then, check its CUDA compatibility on NVIDIA’s official site.C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\vX.X
. In this case, X.X represents the specific version of CUDA you are installing.CUDA\_PATH
and PATH
variables point to the correct CUDA directories:*echo %CUDA\_PATH%*
*echo %PATH%*
bin\\cudnn\*.dll to C:\\Program Files\\NVIDIA\\CUDNN\\vx.x\\bin,
include\\cudnn\*.h to C:\\Program Files\\NVIDIA\\CUDNN\\vx.x\\include,
lib\\x64\\cudnn\*.lib to C:\\Program Files\\NVIDIA\\CUDNN\\vx.x\\lib.
Replace ‘x.x’ with your version number.C:\\Program Files\\NVIDIA\\CUDNN\\vx.x\\bin
to ensure you can access cuDNN executables properly.cudnn64_x.dll
file in the bin directory and .h
header files in the include directory.C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\vX.X
. Replace X.X with the version of CUDA that is installed (e.g., v11.8).C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\vX.X\\bin
. You may also find: C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\vX.X\\libnvvp
. If it’s not there, add it manually to help the system locate CUDA executables.curl
is installed on your system:sudo apt update
sudo apt install curl
sudo ubuntu-drivers autoinstall
Then, make sure to reboot your system after driver installationsudo reboot
curl -fsSL https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/3bf863cc.pub | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-cuda-keyring.gpg
The curl -fsSL https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/3bf863cc.pub
command uses curl to retrieve the public key from the designated URL. The flags included are:| sudo gpg --dearmor -o /usr/share/keyrings/nvidia-cuda-keyring.gpg
segment takes the output from the curl directive into gpg
, which converts the key from ASCII to binary format and saves it in the chosen location. The sudo command guarantees you have the required permissions./usr/share/keyrings/nvidia-cuda-keyring.gpg
, allowing the Ubuntu system to verify the package integrity from NVIDIA’s CUDA repository.echo "deb [signed-by=/usr/share/keyrings/nvidia-cuda-keyring.gpg] https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/ /" | sudo tee /etc/apt/sources.list.d/cuda-repository.list
echo "deb \[signed-by=/usr/share/keyrings/nvidia-cuda-keyring.gpg\] https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86\_64/
: This command sets up a line that indicates the repository URL and the keyring for package signing.| *sudo tee /etc/apt/sources.list.d/cuda-repository.list
: This command sends the output from echo to tee, which writes it into the specified file or creates it if it doesn’t exist. The sudo ensures you have permission to alter system files.sudo apt update
This guarantees that Ubuntu can recognize and fetch packages from the NVIDIA CUDA repository.sudo apt install cuda
This command will install all the CUDA components necessary for GPU acceleration, including compilers and libraries. It’s important to note that this will install the latest version of CUDA. If you’re looking for a particular version, you’ll need to specify it, such as sudo apt install cuda-11-814
.export PATH=/usr/local/cuda/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
The first line places /usr/local/cuda/bin
at the beginning of your PATH, making the nvcc compiler accessible./usr/local/cuda/lib64
to your LD_LIBRARY_PATH, assisting the system in locating CUDA libraries. The specific paths will depend on the installed version of CUDA..bashrc
file is a hidden shell script found within your home directory that is executed each time you initiate a new interactive terminal session within the Bash shell. It includes commands for setting up your environment, like environment variables, aliases, and functions, which customize and manage your shell behavior each time you launch a terminal..bashrc
so the new enviornment variables take effect right away:source ~/.bashrc
nvcc --version
If CUDA is correctly installed, this command will display the installed CUDA version.sudo apt-get install libcudnn8=8.x.x.x-1+cudaX.X
sudo apt-get install libcudnn8-dev=8.x.x.x-1+cudaX.X
tar -xf cudnn-linux-x86_64-x.x.x.x_cudaX.X-archive.tar.xz
Update x.x.x.x
(cuDNN version) and X.X
(CUDA version) to correspond with the versions stated in your archive’s name.sudo cp cudnn-*-archive/include/cudnn*.h /usr/local/cuda/include/
sudo cp -P cudnn-*-archive/lib/libcudnn* /usr/local/cuda/lib64/
sudo chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn*
This series of instructions copy the cuDNN header files (cudnn\*.h
) to the CUDA include folder and copy the cuDNN library files (libcudnn\
) to the CUDA library folder. By using the \-P
option, any symbolic links will be maintained during this copy. chmod a+r
grants read permissions to all users for these files, thereby ensuring they are accessible across the system.sudo ldconfig
This step ensures that your operating system recognizes the newly added cuDNN libraries.cudnn.h
:cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2
This command will display the cuDNN version installed on your system by extracting specific lines from the cudnn.h
header file. The component grep CUDNN_MAJOR -A 2
narrows the output to display the major version number alongside the subsequent two lines, usually indicating the minor and patch version numbers.#define CUDNN_MAJOR 8
#define CUDNN_MINOR 9
#define CUDNN_PATCHLEVEL 2
PATH
and LD_LIBRARY_PATH
so your system can locate cuDNN and CUDA files.~/.bashrc
file:export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
Then, apply the changes in the current shell session:source ~/.bashrc
Framework | Supported CUDA Versions | Supported cuDNN Versions | Notes |
---|---|---|---|
Tensorflow | 11.2 - 12.2 | 8.1+ | TensorFlow 2.15 is compatible with CUDA 12.2. Prior versions may require specific CUDA versions. |
PyTorch | 11.3 - 12.1 | 8.3.2+ | PyTorch 2.1 is compatible with CUDA versions 11.8 and 12.1. The exact versions will vary based on the PyTorch release. |
MXNet | 10.1 - 11.7 | 7.6.5 - 8.5.0 | MXNet 1.9.1 supports up to CUDA 11.7 and cuDNN 8.5.0. |
Caffee | 10.0 - 11.x | 7.6.5 - 8.x | Caffe typically requires manual compilation. It is advisable to verify specific version requirements. |
pip install tensorflow[and-cuda]
This command installs TensorFlow along with necessary CUDA dependencies. For Windows users, GPU support is generally enabled through WSL2(Windows Subsystem for Linux 2) or via the TensorFlow-DirectML-Plugin.import tensorflow as tf
print(tf.config.list_physical_devices('GPU'))
If TensorFlow detects your GPU, you should see at least one physical device mentioned in the results.pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
This command will install the latest compatible versions of torch, torchvision, and torchaudio built for CUDA 12.1. You must make sure you have the appropriate CUDA 12.1 drivers installed on your system for optimal performance.import torch
print(torch.cuda.is_available()) # Should return True if everything is correct
A True
output means PyTorch can recognize your GPU.torch.nn.DataParallel
or DistributedDataParallel. To see how many GPUs PyTorch identifies, run:torch.cuda.device_count()
pip install mxnet-cu``x
The placeholder cu11x
should be replaced with the actual version, suchc as cu110
for CUDA 11.0 or cu113
for CUDA 11.3import mxnet as mx
print (mx.context.num_gpus())
If you see a non-zero result, that means MXNet can access your GPUs.pip
and wheel are updated to their latest versions:python3 -m pip install --upgrade pip wheel
python 3 -m pip install nvidia-cudnn-cu12
To install Cuda 11, use the following command:python 3 -m pip install nvidia-cudnn-cu11
For a specific version of cuDNN (e.g. 9.x.y.z), you can specify the version number:python3 -m pip install nvidia-cudnn-cu12==9.x.y.z
cudnn64\_x.dll
(for Windows) or libcudnn.so
(for Linux) is placed within the same directory as your CUDA installation. Also, verify that LD\_LIBRARY\_PATH
or PATH
includes the directory where these libraries reside.PATH
.nvcc
they recognize.PATH
or LD_LIBRARY_PATH
points to an old or conflicting CUDA version. Always check that your environment variables correspond to the correct paths for the specific CUDA/cuDNN version you plan to use.lspci | grep \-i nvidia
. Finally, compare your GPU model with the specifications listed on NVIDIA’s website.apt get install -y git-lfs pip3
git-lfs clone https://huggingface.co/spaces/deepseek-ai/Janus-Pro-7B
pip install -r requirements.txt spaces omegaconf einops timm spaces torchvision attrdict
python app.py - -share
This will download the Janus Pro model into the HuggingFace cache, and then launch the web application run by Gradio. This can be accessed anywhere on any browser by using the shared, public link.new
keyword to create an instance of a class, the constructor is invoked and the object of the class is returned. Since constructor can only return the object to class, it’s implicitly done by java runtime and we are not supposed to add a return type to it. If we add a return type to a constructor, then it will become a method of the class. This is the way java runtime distinguish between a normal method and a constructor. Let’s assume we have following code in Employee
class.public Employee() {
System.out.println("Employee Constructor");
}
public Employee Employee() {
System.out.println("Employee Method");
return new Employee();
}
Here the first one is a constructor, notice that there is no return type and no return statement. The second one is a normal method where we are again calling the first constructor to get Employee instance and return it. It’s recommended to not have method name same as the class name because it creates confusion.package com.journaldev.constructor;
public class Data {
public static void main(String[] args) {
Data d = new Data();
}
}
package com.journaldev.constructor;
public class Data {
//no-args constructor
public Data() {
System.out.println("No-Args Constructor");
}
public static void main(String[] args) {
Data d = new Data();
}
}
Now when we will call new Data()
, then our no-args constructor will be called. Below image illustrates this behavior, check the console output of the program. package com.journaldev.constructor;
public class Data {
private String name;
public Data(String n) {
System.out.println("Parameterized Constructor");
this.name = n;
}
public String getName() {
return name;
}
public static void main(String[] args) {
Data d = new Data("Java");
System.out.println(d.getName());
}
}
package com.journaldev.constructor;
public class Data {
private String name;
private int id;
//no-args constructor
public Data() {
this.name = "Default Name";
}
//one parameter constructor
public Data(String n) {
this.name = n;
}
//two parameter constructor
public Data(String n, int i) {
this.name = n;
this.id = i;
}
public String getName() {
return name;
}
public int getId() {
return id;
}
@Override
public String toString() {
return "ID="+id+", Name="+name;
}
public static void main(String[] args) {
Data d = new Data();
System.out.println(d);
d = new Data("Java");
System.out.println(d);
d = new Data("Pankaj", 25);
System.out.println(d);
}
}
public
and default
access is still fine, but what is the use of making a constructor private? In that case any other class won’t be able to create the instance of the class. Well, a constructor is made private in case we want to implement singleton design pattern. Since java automatically provides default constructor, we have to explicitly create a constructor and keep it private. Client classes are provided with a utility static method to get the instance of the class. An example of private constructor for Data
class is given below.// private constructor
private Data() {
//empty constructor for singleton pattern implementation
//can have code to be used inside the getInstance() method of class
}
this
keyword to call another constructor of the class. Sometimes it’s used to set some default values of the class variables. Note that another constructor call should be the first statement in the code block. Also, there should not be recursive calls that will create an infinite loop. Let’s see an example of constructor chaining in java program.package com.journaldev.constructor;
public class Employee {
private int id;
private String name;
public Employee() {
this("John Doe", 999);
System.out.println("Default Employee Created");
}
public Employee(int i) {
this("John Doe", i);
System.out.println("Employee Created with Default Name");
}
public Employee(String s, int i) {
this.id = i;
this.name = s;
System.out.println("Employee Created");
}
public static void main(String[] args) {
Employee emp = new Employee();
System.out.println(emp);
Employee emp1 = new Employee(10);
System.out.println(emp1);
Employee emp2 = new Employee("Pankaj", 20);
System.out.println(emp2);
}
@Override
public String toString() {
return "ID = "+id+", Name = "+name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
I have overridden the toString() method to print some useful information about Employee object. Below is the output produced by above program.Employee Created
Default Employee Created
ID = 999, Name = John Doe
Employee Created
Employee Created with Default Name
ID = 10, Name = John Doe
Employee Created
ID = 20, Name = Pankaj
Notice how one constructor is being called from another constructor, that’s called constructor chaining process.super
keyword. Let’s have a look at an example of using super class constructor. Note that super constructor call should be the first statement in the child class constructor. Also when instantiating child class constructor, java first initializes the super class and then child class. So if the super class constructor is not explicitly called then default or no-args constructor is called by java runtime. Let’s understand these concepts through some example program. Let’s assume we have two classes like below.package com.journaldev.constructor;
public class Person {
private int age;
public Person() {
System.out.println("Person Created");
}
public Person(int i) {
this.age = i;
System.out.println("Person Created with Age = " + i);
}
}
package com.journaldev.constructor;
public class Student extends Person {
private String name;
public Student() {
System.out.println("Student Created");
}
public Student(int i, String n) {
super(i); // super class constructor called
this.name = n;
System.out.println("Student Created with name = " + n);
}
}
Now if we create a Student object like below;Student st = new Student();
What will be the output produced? The output of the above code will be:Person Created
Student Created
So the call went to the no-args constructor of Student class since there was no super call in the first statement the no-args or default constructor of Person class is called. Hence the output. What if we are using parameterized constructor of Student class as Student st = new Student(34, "Pankaj");
, the output will be:Person Created with Age = 34
Student Created with name = Pankaj
Here the output is clear because we are explicitly calling superclass constructor, so Java doesn’t need to do any extra work from their side.Fruits
like below.package com.journaldev.constructor;
import java.util.ArrayList;
import java.util.List;
public class Fruits {
private List<String> fruitsList;
public List<String> getFruitsList() {
return fruitsList;
}
public void setFruitsList(List<String> fruitsList) {
this.fruitsList = fruitsList;
}
public Fruits(List<String> fl) {
this.fruitsList = fl;
}
public Fruits(Fruits fr) {
List<String> fl = new ArrayList<>();
for (String f : fr.getFruitsList()) {
fl.add(f);
}
this.fruitsList = fl;
}
}
Notice that Fruits(Fruits fr)
is performing a deep copy to return the copy of the object. Let’s look at a test program to understand why it’s better to have copy constructor to copy an object.package com.journaldev.constructor;
import java.util.ArrayList;
import java.util.List;
public class CopyConstructorTest {
public static void main(String[] args) {
List<String> fl = new ArrayList<>();
fl.add("Mango");
fl.add("Orange");
Fruits fr = new Fruits(fl);
System.out.println(fr.getFruitsList());
Fruits frCopy = fr;
frCopy.getFruitsList().add("Apple");
System.out.println(fr.getFruitsList());
frCopy = new Fruits(fr);
frCopy.getFruitsList().add("Banana");
System.out.println(fr.getFruitsList());
System.out.println(frCopy.getFruitsList());
}
}
The output of the above program is:[Mango, Orange]
[Mango, Orange, Apple]
[Mango, Orange, Apple]
[Mango, Orange, Apple, Banana]
Notice that when copy constructor is used, both the original object and its copy are unrelated to each other and any modifications in one of them will not reflect into other. That’s all for the constructor in java. // This is a Spring component class for UserService.
// It is used to manage the user data and operations.
@Component
public class UserService {
// This is a final field for UserRepository.
// It is used to access the user data.
private final UserRepository userRepository;
// This is a constructor for UserService.
// It is used to initialize the UserRepository.
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
import jakarta.persistence.*;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
// **Default Constructor (Required by Hibernate)**
public User() {
}
// **Parameterized Constructor (For Custom Initialization)**
public User(String name, String email) {
this.name = name;
this.email = email;
}
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
void
. Constructors help in setting up initial values for object properties and ensure that an object is in a valid state from the beginning.Feature | Constructors | Methods |
---|---|---|
Purpose | Initialize objects | Define behavior |
Invocation | Automatically called | Explicitly invoked |
Return Type | No return type | Can return a value |
Overloading | Yes | Yes |
Overriding | No | Yes |
Access Modifiers | Yes | Yes |
Static | No | Yes |
Final | No | Yes |
Abstract | No | Yes |
Synchronized | No | Yes |
new
keyword.Feature | Constructors | Objects |
---|---|---|
Purpose | Initializes objects | Represents an instance of a class |
Creation | Executed once per object creation | Created using the new keyword |
Duration | Executes once | Persists in memory and can be used multiple times |
Role | Sets initial state of an object | Represents a real-world entity or concept |
import torch
y = torch.tensor([2.0, 3.0]); print(y**3 if y.sum() > 3 else y/3)
PyTorch builds the computation graph dynamically, allowing you to incorporate logical branches (if x.sum() > 3) directly in Python, with interpretation occurring at runtime.import tensorflow as tf
@tf.function
def operation(y, z):
return tf.where(tf.reduce_sum(y) > 3, y**3, y/3)
y = tf.constant([2.0, 3.0, 4.0])
z = tf.constant([3.0, 4.0])
res = operation(y, z)
print(res.numpy())
Using the tf.function
decorator converts this Python function internally into a static graph. Although TensorFlow 2.x allows for eager execution, tf.function
compiles operations into a static graph for potential optimizations. This demonstrates the legacy of TensorFlow’s static graph architecture.import torch
script = torch.jit.trace(torch.nn.Linear(3, 2), torch.randn(1, 3));
print(script.code)
torch.jit.trace( )
monitors your model (torch.nn.Linear(3, 2)) using a sample tensor input (torch.randn(1, 3)).script.code
will display the TorchScript code that will be generated. This demonstrates the transition of PyTorch from a dynamic graph configuration to a trace-based static representation.torch.nn
module or other enhanced tools such as torchvision
for image-related tasks, or torchtext
for processing natural language. Another higher-level framework is PyTorch Lightning, which reduces the boilerplate code involved in tasks like training loops, checkpointing, and multi-GPU support.tf.function
decorators that optimize graph optimization. Its popularity stems mainly from its ease of use, making it particularly attractive for those aiming to deploy models without unnecessary complications.import tensorflow as tf
@tf.function
def op(y): return y + "error"
print(op(tf.constant([2.0, 3.0]))) # Triggers autograph conversion error
Output:TypeError: Input 'y' of 'AddV2' Op has type string that does not match type float32 of argument 'x'.
The error arises instantly in the PyTorch example because it uses dynamic graph execution, meaning each operation takes place in real-time. Adding a string to a tensor is an invalid action, leading Python to issue a TypeError. This makes identifying and resolving the issue straightforward.torch.cuda.amp
for implementing automatic mixed precision.tf.data
, an API designed for developing optimized input pipelines that handle large datasets, enabling parallel I/O operations. With functions like map, shuffle, and prefetch
, tf.data can optimize GPU-based data preprocessing.tensorboardX
or by means of direct integration (e.g., torch.utils.tensorboard
).input()
Functioninput()
function. It reads a string from the keyboard and returns it.name = input("Enter your name: ")
print("Hello, " + name + "!")
input()
returns a string, you must convert it to an integer when necessary:age = int(input("Enter your age: "))
print("You are", age, "years old.")
float()
function, which converts a string to a floating-point number.price = float(input("Enter the price: "))
print("The price is", price)
try-except
blocks. This approach allows you to catch and manage exceptions that might be raised during the input process, ensuring your program remains robust and user-friendly.while True:
try:
number = int(input("Enter an integer: "))
break
except ValueError:
print("Invalid input! Please enter a valid integer.")
For learning more about handling different data types, check out our tutorial on Python Data Types.split()
method, which divides a string into a list of substrings based on a specified separator. In the case of user input, we can use split()
to separate multiple values entered by the user.split()
to receive two string inputs from the user:x, y = input("Enter two numbers separated by space: ").split()
print("First number:", x)
print("Second number:", y)
However, if you need to perform numerical operations on these inputs, you’ll need to convert them to numerical types. This can be achieved using the map()
function, which applies a given function to each item of an iterable (in this case, the list of strings returned by split()
). Here’s how to modify the previous example to convert the inputs to integers:x, y = map(int, input("Enter two numbers: ").split())
print("Sum:", x + y)
By using map()
to convert the inputs to integers, you can perform arithmetic operations on them as needed.sys.argv
method allows you to access these arguments within your script.sys.argv
to read command-line arguments:script.py
:import sys
# sys.argv is a list that contains the script name and all arguments passed to it
print("Script name:", sys.argv[0]) # sys.argv[0] is the script name itself
# Check if any arguments were passed
if len(sys.argv) > 1:
print("Arguments:", sys.argv[1:]) # sys.argv[1:] contains all arguments except the script name
To run the script with arguments, use the following command in your terminal or command prompt:python script.py Hello World
In this example, Hello
and World
are the arguments passed to the script. The script will output the script name and the arguments provided.Tkinter
allows you to create simple GUI applications with a minimal amount of code.Tkinter
to receive user input in a GUI application:import tkinter as tk
def get_input():
# Retrieve the text entered by the user in the Entry field
user_input = entry.get()
# Update the Label to display the user's input
label.config(text=f"You entered: {user_input}")
# Create the main window of the application
root = tk.Tk()
# Create an Entry field for user input
entry = tk.Entry(root)
entry.pack() # Add the Entry field to the window
# Create a Button to trigger the get_input function
btn = tk.Button(root, text="Submit", command=get_input)
btn.pack() # Add the Button to the window
# Create a Label to display the user's input
label = tk.Label(root, text="")
label.pack() # Add the Label to the window
# Start the Tkinter event loop
root.mainloop()
This example demonstrates how to create a simple GUI application that prompts the user for input, processes that input, and displays it back to the user.try-except
blocks to catch and handle exceptions that may occur during input processing. For instance, when asking the user to enter an integer, you can use a try-except
block to handle cases where the user enters a non-integer value.# This code block is designed to repeatedly prompt the user for an integer input until a valid integer is entered.
while True: # This loop will continue indefinitely until a break statement is encountered.
try:
# The input() function is used to get user input, which is then passed to int() to convert it to an integer.
# If the input cannot be converted to an integer (e.g., if the user enters a string or a float), a ValueError is raised.
num = int(input("Enter an integer: "))
# If the input is successfully converted to an integer, the loop is exited using the break statement.
break
except ValueError:
# If a ValueError is raised, it means the input cannot be converted to an integer.
# In this case, an error message is printed to the user, prompting them to enter a valid integer.
print("Invalid input! Please enter a valid integer.")
# After the loop is exited, the program prints out the valid integer entered by the user.
print("You entered:", num)
try-except
blocks can be used to catch and handle errors in a way that doesn’t disrupt the application’s flow. For example, when reading from a file, you can use a try-except
block to handle cases where the file does not exist or cannot be read.# Try to open the file "example.txt" in read mode
try:
with open("example.txt", "r") as file:
# Read the content of the file
content = file.read()
# Print the content of the file
print("File content:", content)
# Handle the case where the file is not found
except FileNotFoundError:
print("File not found!")
# Handle any other exceptions that may occur
except Exception as e:
print("An error occurred:", str(e))
# This code block prompts the user to enter a username, with a maximum length of 20 characters.
username = input("Please enter your username (maximum 20 characters): ")
# If the length of the username is greater than 20, it is truncated to 20 characters.
if len(username) > 20:
username = username[:20]
print("Your username has been truncated to 20 characters.")
# The program then prints the username entered by the user.
print("Your username is:", username)
html
module provides a convenient way to escape HTML characters in user input. For example, when displaying user input on a web page, you can use html.escape()
to prevent XSS attacks.# This code block imports the 'html' module to use its 'escape' function for sanitizing user input.
import html
# It then prompts the user to enter a string using the 'input' function.
user_input = html.escape(input("Enter a string: "))
# The 'html.escape' function is used to escape any HTML characters in the user's input to prevent XSS attacks.
# This ensures that any special characters in the input are replaced with their HTML entity equivalents, making the input safe to display in a web page.
# Finally, the sanitized user input is printed to the console.
print("Sanitized input:", user_input)
or
operator to assign a default value if the user input is empty or invalid. For instance, when asking the user to enter their name, you can provide a default value of “Guest” if the user does not enter a name.# This code block prompts the user to enter their name and then prints a greeting message.
# The input function is used to get user input, and the or "Guest" part ensures that if the user doesn't enter anything, the default name "Guest" is used.
name = input("Enter your name: ") or "Guest"
# The f-string is used to format the greeting message with the user's name.
print(f"Hello, {name}!")
By following these best practices, you can ensure that your Python application handles user input in a way that is secure, efficient, and user-friendly.input()
function to prompt the user for input and store their response in a variable. Here’s a simple example:user_input = input("Enter something: ")
print("You entered:", user_input)
while
loop to repeatedly prompt the user for input until a valid integer is entered. Here’s an example code block that demonstrates this:# This code block repeatedly prompts the user to enter an integer until a valid integer is entered.
while True: # This loop will continue to run indefinitely until a valid integer is entered.
user_input = input("Enter an integer: ") # This line prompts the user to enter an integer and stores the input in the 'user_input' variable.
if user_input.isdigit(): # This condition checks if the user's input consists only of digits, indicating a valid integer.
num = int(user_input) # If the input is a valid integer, it is converted to an integer and stored in the 'num' variable.
print("You entered:", num) # This line prints a message to the console indicating the valid integer entered by the user.
break # This line breaks out of the loop, ending the program.
else:
print("Invalid input! Please enter a valid integer.") # If the input is not a valid integer, this message is printed to the console, prompting the user to enter a valid integer.
This code block ensures that the program will continue to prompt the user for input until a valid integer is entered, making it a robust way to handle user input in Python.split()
method to divide the input string into multiple parts based on a specified separator, such as a space. The map()
function can then be used to convert each part into the desired data type, such as an integer.x, y = map(int, input("Enter two numbers separated by space: ").split())
print("First number:", x)
print("Second number:", y)
input()
?sys.argv
list. The first element of this list, sys.argv[0]
, is the script name itself. The rest of the elements are the arguments passed to the script.import sys
# Check if any command-line arguments were provided
if len(sys.argv) > 1:
# Print the arguments received
print("Command-line arguments received:", sys.argv[1:])
else:
# Inform the user if no arguments were provided
print("No command-line arguments provided.")
In this example, the script checks if any arguments were provided by checking the length of sys.argv
. If there are more than one elements in sys.argv
(i.e., at least one argument was provided), it prints the arguments received. If not, it informs the user that no arguments were provided.input()
function. This function returns a string, which can be stored in a variable for further processing. Here’s an example:user_input = input("Please enter your name: ")
print("Hello, " + user_input + "!")
This code prompts the user to enter their name and then prints a greeting message with their name.input()
function. For example:name = input("Please enter your name: ")
print("Hello, " + name + "!")
In this example, the name
variable stores the input received from the user, and then it is used to print a greeting message.input()
function and convert the input string to an integer or float using the int()
or float()
function, respectively. Here’s an example:age = int(input("Please enter your age: "))
print("You are " + str(age) + " years old.")
This code prompts the user to enter their age, converts the input to an integer, and then prints a message with their age.~/.bashrc
”, but what if you’re not using bash? What if your
bash config is actually in a different file? And how are you supposed to figure
out which directory to add anyway?ps -p $$ -o pid,comm=
97295 bash
97295 zsh
$$
isn’t valid syntax in fish, but in any case the error
message tells you that you’re using fish, which you probably already knew)~/.zshrc
~/.bashrc
, but it’s complicated, see the note in the next section~/.config/fish/config.fish
(you can run echo $__fish_config_dir
if you want to be 100% sure)~/.bashrc
, ~/.bash_profile
, and ~/.profile
.echo hi there
to your ~/.bashrc
~/.bashrc
is being used! Hooray!~/.bash_profile
~/.profile
if the first two options don’t work.http-server
and it doesn’t work, like this:$ npm install -g http-server
$ http-server
bash: http-server: command not found
How do you find what directory http-server
is in? Honestly in general this is
not that easy – often the answer is something like “it depends on how npm is
configured”. A few ideas:cargo
, npm
, homebrew
, etc),
when you first set it up it’ll print out some directions about how to update
your PATH. So if you’re paying attention you can get the directions then.PATH
for younpm config get prefix
(then append /bin/
)go env GOPATH
(then append /bin/
)asdf info | grep ASDF_DIR
(then append /bin/
and /shims/
)http-server
is
in ~/.npm-global/bin
. I can make sure that it’s the right directory by trying to
run the program http-server
in that directory like this:$ ~/.npm-global/bin/http-server
Starting up http-server, serving ./public
It worked! Now that you know what directory you need to add to your PATH
,
let’s move to the next step!~/.npm-global/bin/
)~/.bashrc
, ~/.zshrc
, or ~/.config/fish/config.fish
)export PATH=$PATH:~/.npm-global/bin/
(obviously replace ~/.npm-global/bin
with the actual directory you’re trying to add)path=(
$path
~/.npm-global/bin
)
fish instructions:set PATH $PATH ~/.npm-global/bin
(in fish you can also use fish_add_path
, some notes on that further down)bash
to start a new shell (or zsh
if you’re using zsh, or fish
if you’re using fish)python3
installed, which I
can see by running which -a
:$ which -a python3
/usr/bin/python3
/opt/homebrew/bin/python3
The one your shell will use is the first one listed./opt/homebrew/bin
) to the beginning of your PATH instead, by putting this in
your shell’s config file (it’s /opt/homebrew/bin/:$PATH
instead of the usual $PATH:/opt/homebrew/bin/
)export PATH=/opt/homebrew/bin/:$PATH
or in fish:set PATH ~/.cargo/bin $PATH
/home/bork/bin/my-program
echo "PATH=$PATH"
.source
cargo
(Rust’s installer) for the first time, it gives you
these instructions for how to set up your PATH, which don’t mention a specific
directory at all.This is usually done by running one of the following (note the leading DOT):
. "$HOME/.cargo/env" # For sh/bash/zsh/ash/dash/pdksh
source "$HOME/.cargo/env.fish" # For fish
The idea is that you add that line to your shell’s config, and their script
automatically sets up your PATH
(and potentially other things) for you.brew shellenv
), and there are
two ways to approach this:. "$HOME/.cargo/env"
to your shell’s config). "$HOME/.cargo/env"
in my shell (or the fish version if using fish)echo "$PATH" | tr ':' '\n' | grep cargo
to figure out which directories it added/Users/bork/.cargo/bin
and shorten that to ~/.cargo/bin
~/.cargo/bin
to PATH (with the directions in this post)fish_add_path
fish_add_path
that you can run to add a directory to your PATH
like this:fish_add_path /some/directory
This will add the directory to your PATH
, and automatically update all
running fish shells with the new PATH
. You don’t have to update your config
at all! This is EXTREMELY convenient, but one downside (and the reason I’ve
personally stopped using it) is that if you ever need to remove the directory
from your PATH
a few weeks or months later because maybe you made a mistake,
it’s kind of hard to do (there are
instructions in this comments of this github issue though).