Fix formatting in various posts

This commit is contained in:
ItsDrike 2023-12-11 19:12:42 +01:00
parent 523fefed1b
commit c5b1c9da0a
Signed by: ItsDrike
GPG key ID: FA2745890B7048C0
7 changed files with 64 additions and 50 deletions

View file

@ -89,7 +89,7 @@ Consider this code:
```
In the example here, we can see that python keeps a reference count for the empty list object, and in this case, it was
3. The list object was referenced by a, b and the argument passed to `sys.getrefcount`. If we didn't have locks,
\3. The list object was referenced by a, b and the argument passed to `sys.getrefcount`. If we didn't have locks,
threads could attempt to increase the reference count at once, this is a problem because what would actually happen
would go something like this:
@ -167,6 +167,7 @@ become incorrect in a way that's hard to see during code reviews.
## Debugging multi-threaded code
As an example, this is a multi-threaded code that will pass all tests and yet it is full of bugs:
```python
import threading
@ -183,6 +184,7 @@ for _ in range(5):
threading.Thread(target=foo).start()
print("Finished")
```
When you run this code, you will most likely get a result that you would expect, but it is possible that you could also
get a complete mess, it's just not very likely because the code runs very quickly. This means you can write code
multi-threaded code that will pass all tests and still fail in production, which is very dangerous.
@ -192,6 +194,7 @@ behind every instruction to ensure that it is safe if a switch happens during th
it is advised to run the code multiple times because there is a chance of getting the correct result even with this
method since it always is one of the possibilities, this is why multi-threaded code can introduce a lot of problems.
This would be the code with this "fuzzing" method applied:
```python
import threading
import time
@ -219,6 +222,7 @@ for _ in range(5):
threading.Thread(target=foo).start()
print("Finished")
```
You may also notice that I didn't just add `fuzz()` call to every line, I've also split the line that incremented
counter into 2 lines, one that reads the counter and another one that actually increments it, this is because
internally, that's what would be happening it would just be hidden away, so to add a delay between these instructions
@ -226,6 +230,7 @@ I had to actually split the code like this. This makes it almost impossible to t
problem.
It is possible to fix this code with the use of locks, which would look like this:
```python
import threading
@ -257,6 +262,7 @@ for t in worker_threads:
with printer_lock:
print("Finished")
```
As we can see, this code is a lot more complex than the previous one, it's not terrible, but you can probably imagine
that with a bigger codebase, this wouldn't be fun to manage.
@ -264,6 +270,7 @@ Not to mention that there is a core issue with this code. Even though the code
bugs, it is still wrong. Why? When we use enough locks in our multi-threaded code, we may end up making it full
sequential, which is what happened here. Our code is running synchronously, with huge amount of overhead from the locks
that didn't need to be there and the actual code that would've been sufficient looks like this:
```python
counter = 0
print("Starting")
@ -273,6 +280,7 @@ for _ in range(5)
print("----------------------")
print("Finished")
```
While in this particular case, it may be pretty obvious that there was no need to use threading at all, there are a lot
of cases in which it isn't as clear and I have seen some projects with code that could've been sequential but they were
already using threading for something else and so they made use of locks and added some other functionality, which made

View file

@ -58,18 +58,22 @@ youtube-dl, download the video and then stream it from our machine instead of fr
download the file from our server that has now downloaded this video, however that's way too crude.
There is a much nicer method that we can use, and it is still utilizing pure SSH:
```sh
ssh -f -N -D 1080 user@server
```
This command will start SSH in background (`-f`), it won't run any actual commands (`-N`) and it will be bound to the
port 1080 on our machine (`-D`). This means that we can utilize this port as a SOCK and make our server act as SOCKS5
proxy. This kind of proxy will even be supported by most web browsers, allowing you to simply specify the address
(in our case `127.0.0.1:1080`) and have all traffic go through this external server.
To test that this connection really does work, we could use the `curl` command like this:
```sh
curl --max-time 3 -x socks5h://127.0.0.1:1080 https://itsdrike.com
```
If we see the HTML code as the output, it means that we've obtained the content of the specified website through our
socks5 proxy, that we've established through simple SSH.
@ -93,9 +97,11 @@ around SSH and it will simply utilize SSH in the background, which is also why w
server side for this to work properly, as long as we simply have the SSH server running, `sshuttle` will work fine.
We can use sshuttle with a command like this:
```sh
sudo sshuttle -r user@machine 172.67.161.205/24 -vv
```
Which will forward all traffic destined for the particular address block (the IP/number is called the CIDR notation, it
essentially specifies which IPs should be affected depending on the number after /, you can read more about it on
[wikipedia](https://wikiless.org/wiki/Classless_Inter-Domain_Routing?lang=en)). In this case, I've specified the IP of
@ -112,12 +118,14 @@ you need to think about this ahead of time.
You could also simply redirect the port 22 to something else using iptables instead of having to mess with the SSH
config. You would do that with this command:
```sh
sudo iptables -t nat -I PREROUTING -p tcp --dport 1234 -j REDIRECT --to-ports 22
```
This command will make port `1234` act as the SSH port, and you could then access the server by specifying this port
instead of the default port in the ssh command:
```
ssh -f -N -D 1080 user@server -p 1234
```
@ -213,9 +221,11 @@ Turns out that even with a security measure as strict as only allowing access to
somewhat make our way to our server, by essentially telling it to map all exiting traffic from port 443 to port 22.
To do this, we would use a command like this:
```sh
ssh -o "ProxyCommand nc -X connect -x proxy_server:3128 our_server_IP 443" user@our_server_IP
```
Here we're essentially sending a proxy command to the web proxy server (listening on port 3128) to through the port 443
to our_server_IP and make requests to the SSH's default port (22) on our_server_IP. Making the actual proxy server
access our server on port 22.
@ -235,8 +245,10 @@ really be possible.
To explain how easy it is to discover something like this, basically all that's needed is to run a single command on
that web proxy:
```sh
iptables -t nat -L
```
And look for the output policy destinations. Even though many network admins won't do this, you shouldn't ever risk
doing something silly like this, because if you will get discovered, you could get into some serious trouble

View file

@ -78,10 +78,9 @@ configured account, you can disable it with:
```bash
git config --local commit.gpgsign false
```
{{< /notice >}}
## Git credentials
User configuration is one thing, but there's another important part of account configuration to consider, that is
@ -239,7 +238,6 @@ The cache credential helper will never write your credential data to disk, altho
Unix sockets. These sockets are protected using file permissions that are limited to the user who stored them though,
so even in multi-user machine, generally speaking, they are secure.
#### Custom credential helpers
Apart from these default options, you can also use [custom

View file

@ -144,4 +144,3 @@ this byte-code with an interpreter. This is also known as Just In Time (JIT) com
Most languages tend to only be one or the other, but there are a fair few that follow this hybrid implementation, most
notably, these are: Java, C#, Python, VB.NET

View file

@ -36,10 +36,10 @@ systems is, as the name would imply, manage the database. It controls how the da
if there should be some internal compression of this database or things like that.
Even though there are a lot of choices for DBMS, no matter which one we end up using, on the surface, they will be
doing exactly the same thing. Storing tables of data. Each item in the database usually has some *primary key*, which
doing exactly the same thing. Storing tables of data. Each item in the database usually has some _primary key_, which
is a unique identifier for given column of data. We can also have composite primary keys, where there would be multiple
slots which are unique when combined, but don't necessarily need to be unique on their own. We can also use what's
called a *foreign key*, which is basically the primary key of something in another database table, separate from the
called a _foreign key_, which is basically the primary key of something in another database table, separate from the
current one, to avoid data repetition. This would be an example of the data tables that a database could hold:
Table of students:
@ -68,8 +68,8 @@ Student Grades:
| ... | ... | ... | ... |
{{< /table >}}
Here we can see that the *Student Grades* table doesn't have a standalone unique primary key, like the Students table
has, but rather it has a composite primary key, in this case, it's made of 3 columns: *Student*, *Subject* and *Year*.
Here we can see that the _Student Grades_ table doesn't have a standalone unique primary key, like the Students table
has, but rather it has a composite primary key, in this case, it's made of 3 columns: _Student_, _Subject_ and _Year_.
We can also see that rather than defining the whole student all over again, since we already have the students table,
we can instead simply use the Student ID from which we can look up the given student from this table
@ -148,4 +148,3 @@ Another use-case for databases is when you need to host the data of the database
database, we can simply expose some port and let the DBMS handle interactions with it when our program can simply be
making requests to this remote server. This is usually how we handle using databases with servers, but many client-side
programs are creating their own local databases and using those, simply because using files is ineffective.

View file

@ -134,8 +134,8 @@ return list(result.values())
To preserve the original elements, we used a dict that held the unique hashable memory ids of our objects as keys and
the actual unhashable objects as values. Once we were done, we just returned all of the values in it as a list.
The result of this would be: `[x, y, 1, 2, "hi", Foo(x=5)]`. *(Note that `x`, `y` and `Foo(x=5)` would actually be
printed in the same way, since they're the same class, sharing the same `__repr__`)*. From this output we can clearly
The result of this would be: `[x, y, 1, 2, "hi", Foo(x=5)]`. _(Note that `x`, `y` and `Foo(x=5)` would actually be
printed in the same way, since they're the same class, sharing the same `__repr__`)_. From this output we can clearly
see that even though `x`, `y`, and `Foo(x=5)` are exactly the same thing, sharing the same attributes, they're
different objects and therefore they have different memory ids, which means our algorithm didn't remove them, however
there is now only one `x`, because the second one was indeed exactly the same object, so that did get removed.
@ -217,4 +217,3 @@ one if we know which classes will be used there.
Even though we do have ways to deal with unhashables, if you're in control of the classes, and they aren't supposed to
be mutable, always make sure to add a `__hash__` method to them, so that duplicates can be easily removed in `O(n)`
without any complicated inconveniences.

View file

@ -165,7 +165,6 @@ Here's a list of some definable generic types that are currently present in pyth
| Mapping[str, int] | Mapping from `str` keys to `int` values (immutable) |
{{< /table >}}
In python, we can even make up our own generics with the help of `typing.Generic`:
```python