Cloning Repositories from GitHub
To retrieve a repository from GitHub to your local machine, execute the git clone command followed by the reposiotry's URL.
Begin by navigating to the directoyr where you want to store the files. Right-click and select "Git Bash Here" to open a terminal in that location.
Next, copy the HTTPS or SSH URL of the repository from GitHub and run:
git clone <repository-url>
In case of SSL verification errors, disable certificate checking using:
git config --global http.sslVerify false
After successful execution, verify the integrity of the downloaded files.
Pushing Local Changes to GitHub
To upload changes from your local environment to GitHub, use the following command:
git push -u <repository-url> <branch-name>
Start by creating a new repository on GitHub and copying its HTTPS URL. For example:
git@github.com:user/repo.git
Navigate into the project folder and initiate Git Bash. Then enter the push command with your repository details:
git push -u origin master
You may be prompted to authenticate through your browser.
Updating Remote Repository State
If a file like README.md has been removed locally, synchronize it with the remote repository using:
git add .
git commit -m "Update message"
git push origin master
To fetch updates from GitHub when changes have been made remotely:
git pull --rebase origin master
This ensures your local working directory reflects all recent modifications.
Setting Up SSH Keys for Authentication
If authentication fails, generate an SSH key pair for secure access.
First, configure your Git identity:
git config --global user.name "YourGitHubUsername"
git config --global user.email "your-email@example.com"
Generate a new SSH key pair:
ssh-keygen -t rsa -b 4096 -C "your-email@example.com"
Initialize the SSH agent and add your private key:
ssh-agent -s
ssh-add ~/.ssh/id_rsa
Copy the public key to clipboard:
clip < ~/.ssh/id_rsa.pub
Paste the copied public key into GitHub under Settings > SSH and GPG keys > New SSH key.
The process uses asymmetric encryption: the private key resides on your computer, while the public key is stored on GitHub. This allows authenticated access without transmitting passwords.
Using IntelliJ IDEA for Git Operations
Cloning a Repository
In IntelliJ IDEA, go to VCS > Git > Clone. Enter the repository URL and specify the local path where you want to place the files.
Pushing Changes
Make sure your commits are staged and committed locally. Then, navigate to VCS > Git > Push. Select the appropriate remote and branch to push your changes.
Pulling Updates
From the menu bar, select VCS > Git > Pull to synchronize your local repository with the latest changes from the remote.
Scheduled Tasks with ScheduledExecutorService
The ScheduledExecutorService enables scheduling tasks at fixed rates or delays:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
scheduler.scheduleAtFixedRate(() -> {
System.out.println("Executing task...");
sleep(2);
}, 2, 1, TimeUnit.SECONDS);
Using scheduleWithFixedDelay measures intervals between task completions:
scheduler.scheduleWithFixedDelay(() -> {
System.out.println("Executing task...");
sleep(2);
}, 1, 1, TimeUnit.SECONDS);
Handling Exceptions in Thread Pools
Exceptions within tasks can be caught using try-catch blocks or handled via Future objects returned by submit():
Future<Boolean> future = pool.submit(() -> {
int i = 1 / 0;
return true;
});
try {
Boolean result = future.get();
} catch (ExecutionException e) {
// Handle exception
}
Implementing Periodic Tasks with Time Calculations
Schedule recurring actions based on specific times:
LocalDateTime now = LocalDateTime.now();
LocalDateTime targetTime = now.withHour(12).withMinute(3).withSecond(0).with(DayOfWeek.SUNDAY);
if (now.compareTo(targetTime) > 0) {
targetTime = targetTime.plusWeeks(1);
}
long delay = Duration.between(now, targetTime).toMillis();
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(() -> {
System.out.println("Running periodic task...");
}, delay, 1000, TimeUnit.MILLISECONDS);
ForkJoinPool Usage Example
Use ForkJoinPool for divide-and-conquer algorithms:
ForkJoinPool pool = new ForkJoinPool(4);
Integer result = pool.invoke(new SumTask(5));
Define a recursive task class:
class SumTask extends RecursiveTask<Integer> {
private final int n;
public SumTask(int n) {
this.n = n;
}
@Override
protected Integer compute() {
if (n == 1) {
return 1;
}
SumTask subTask = new SumTask(n - 1);
subTask.fork();
return n + subTask.join();
}
}
Custom Lock Implementation Using AQS
Create a custom lock using AbstractQueuedSynchronizer:
class CustomLock implements Lock {
private final Sync sync = new Sync();
private static class Sync extends AbstractQueuedSynchronizer {
@Override
protected boolean tryAcquire(int arg) {
if (compareAndSetState(0, 1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
@Override
protected boolean tryRelease(int arg) {
setExclusiveOwnerThread(null);
setState(0);
return true;
}
@Override
protected boolean isHeldExclusively() {
return getState() == 1;
}
}
@Override
public void lock() {
sync.acquire(1);
}
@Override
public void unlock() {
sync.release(1);
}
// Other methods omitted
}
ReadWriteLock Pattern
Implement read-write locks for scenarios with frequent reads and infrequent writes:
ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
ReentrantReadWriteLock.ReadLock rl = rwl.readLock();
ReentrantReadWriteLock.WriteLock wl = rwl.writeLock();
rl.lock();
try {
// Reading operations
} finally {
rl.unlock();
}
wl.lock();
try {
// Writing operations
} finally {
wl.unlock();
}
Semaphore for Resource Limitation
Control concurrent access to limited resources:
Semaphore semaphore = new Semaphore(3);
for (int i = 0; i < 10; i++) {
new Thread(() -> {
try {
semaphore.acquire();
// Access resource
sleep(1);
} catch (InterruptedException ignored) {}
finally {
semaphore.release();
}
}).start();
}
CountDownLatch for Synchronization
Wait for multiple threads to complete before proceeding:
CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
new Thread(() -> {
// Perform work
latch.countDown();
}).start();
}
latch.await(); // Wait until all threads finish
These tools streamline development workflows involving version control, thread safety, and concurrent execution.