38% + about 1 month of net income to pay each year as income tax.
There's absolutely no visibility on retirement plan. You just know that you earn "points", with no idea what they're worth.
Also, when you rent in France you have to pay a tax (similar to property tax) which, depending on the city, can be quite high (~1 month of rent/year).
VAT is 22% on most products. Gas is expensive (highways too!!!). Train (TGV) is ridiculously expensive.
So I spent 3 years in Epitech, which forked into 42, and the first 4 weeks aren't a competition but more like an onboarding thing. You basically learn C in 4 weeks, with coding tests pretty much every day. It sets the base and it turns out to be a great way to quickly know if you really wanna be a software engineer.
After these 4 weeks, students start working on group projects and regular CS classes (although teachers are senior students).
The C10k problem is 15-20 years old. Tcl uses select() which can handle a maximum of 1024 FDs. In other words, it would not be able to handle more than 1024 connections in parallel.
Moreover, Linux and FreeBSD have introduced syscalls comparable to select(): epoll (in 2002) and kqueue (in 2000). Those are way faster than select() and I think there's (virtually) no limit on FDs. Tcl must be using select() for its portability I guess.
So, handling a lot of concurrent connections is an old problem. In 2006, the C10k problem was way behind. Even at that time, I would have expected a program to be able to handle thousands of TPS.
"From SMTP filters/routers that handle millions of email deliveries a week to in-memory message journaling (for redundancy) that handle hundreds of transactions per second."
I stopped right there. To me, high performance is for instance, handling millions of emails per minute, thousands or tenth of thousand TPS. This is high performance, real life performance, not seen only in "physic labs and university research centers".
Some comments talk about Tcl using select. If this is true, it would mean a max of 1024 connections in parallel, kind of sad...
Once the stack allocated for a thread, context switches are almost as cheap as a function call.
RiNOO has an event driven scheduler, based on epoll, which resume/release these user-space threads (that I call tasks) according to pending IOs.
The library provides with IO functions (read, write...) which use the RiNOO scheduler.
As a bonus, real threading is quite easy: just need to run a scheduler per thread (see examples with multi-threading).
Callbacks can be avoided using co-routines.
I started a project that uses asynchronous sockets but they appear synchronous. With a bit of abstraction, it's really easy to develop network applications even in C: