- wejście-przetwarzanie-wyjście.
- każdy program da się napisać instrukcją
iforazwhile(a nawet goto/jump zamiast while). - dane przechowujemy w zmiennej. tablica to ułatwienie dla programisty. to grupa zmiennych do których można się dostać po numerze.
- funkcje to ułatwienie dla programisty. grupują powtarzalny kod jak szablon.
- ucz się na początek jednego języka programowania, aż go dobrze poznasz.
- aby dobrze poznać język programowania, trzeba napisać w nim duży projekt np. 100k linii kodu.
- najlepiej się uczyć robiąc projekty np. https://www.udemy.com/course/nauka-pythona-poprzez-tworzenie-gier-w-pygame-zero/
- gromadź swoją wiedzę gdzieś: github markdown, https://obsidian.md - można synchronizować do swojego repozytorium git, https://docusaurus.io/
- https://web.archive.org/web/20150204191826/https://www.vikingcodeschool.com/posts/why-learning-to-code-is-so-damn-hard
- Teach Yourself Programming in Ten Years - Peter Norvig
- Performance from the beginning
więcej
contradictory to https://wiki.c2.com/?MakeItWorkMakeItRightMakeItFast
Ryan Fleury:
“Make it work, then make it fast” as a guiding principle has done an enormous amount of damage to software. It’s slightly easier to accept if the software in question actually works despite being slow. In practice, it’s used to justify mediocrity, and a lack of understanding and responsibility, and thus the software ends up barely working, or not working at all, and wasting a ton of user time.
It’s always a constraint solving problem. You place all screws first, then tighten them all. Performance is one such screw. If you never expose your solution to that constraint, your solution will never be performant. I refuse to accept the idea that you should always place that screw last.
- https://roadmap.sh/
- https://github.com/sjpiper145/MakerSkillTree/blob/main/Coding%20Skill%20Tree/Coding%20Skill%20Tree.pdf
- cursor.sh
- vscode
- neovim
- zed
-
linia komend (cli)
więcej o linii komend
bash, env variables, ls, grep (ripgrep), find (sharkdp/fd), xargs i inne z coreutils -
git
-
sql
- wyrażenia regularne
- system binarny, szestnastkowy itp.
- złożoność to podstawowy wróg programisty: https://grugbrain.dev, KISS, YAGNI
więcej o złożoności
There is a difference between the inherent complexity of the problem you're trying to solve, and the artificial complexity you created by the way you wrote the code. https://x.com/DanielcHooper/status/1784983115196207425
Fools ignore complexity. Pragmatists suffer it. Some can avoid it. Geniuses remove it. http://www.cs.yale.edu/homes/perlis-alan/quotes.html
- https://danielchasehooper.com/posts/good-ideas-in-cs/
- warstwy abstrakcji: Abstraction principle, Rule of three.
więcej o repeat yourself, rule of three
@nicbarkeragain
So many times early in my career I spent way too long on some abstraction / interface in preparation for a second variant, only to find that when I actually built it, the reality of the two was so different that the abstraction made them both worse.
@amfetamigo
what sucks is how they slowly desync. one will have some set of nice things, the other will have this other set of nice things. yet not necessarily worth solving with abstraction either so the only tool left is eternal vigilance
@jimmy__lefevre
wait to have 3 [meaningfully different] use cases before factoring out the code.
więcej
bring on the 10k line files! IMO: most programs flow best (the data transformations are most clear) when written like a novel, not when written like a choose your own adventure book. the split-everything style is useful for novice programmers who need the equivalent of "see spot run. run spot run". but once someone has read tens or hundreds of thousands of lines of code, they will be slowed down by it. it actually harms programmers' growth to avoid thinking about more state at once, because the mind expands to be able to think about more things, by chunking and pattern matching. the brain can already chunk and pattern match, and doesn't need a function declaration or separate file to do so. functions for reuse, not for partitioning. just use comments for blocks instead, if it helps you.
- Essays on programming I think about a lot | benkuhn.net
- matklad: A bunch of things I find myself repeatedly referring to in various discussions!
- imperatywny
- funkcyjny - może być trudne do czytania i zarządzania jak dużo lambd.
więcej
Andrew Kelley o programowaniu funkcyjnym
Finally, I personally despise the functional programming style that uses lambdas everywhere. I find it very difficult to read and maintain code that makes heavy use of inversion of control flow. By not accepting this proposal, Zig will continue to encourage programmers to stick to an imperative programming style, using for loops and iterators. ziglang/zig#1717 (comment)
Casey Muratori:
I do not think functional programming is the proper model for programming. I think it can be a useful way to think about subsets of a program, but it is not appropriate for large-scale work.
the practical behavior of modern computing systems is procedural, not functional, and so it does not benefit you to adopt functional constraints for designing a system. But it's fine for parts of the system that fit within those constraints more naturally.
Broadly, I tend to want to program the hardware, so I want something that allows me to easily express what machine code I wanted. I don't want to have to fight the language or compiler to have the CPU do what I intended.
Anything that I have to think about that isn't something the CPU is actually doing is a hindrance and makes me less happy about programming. I know what I want it to do, and I want that to be as efficient as possible to express.
- programowanie zorientowane obiektowo (OOP)
więcej o OOP
Jonathan Blow on the Problem with Object Oriented
Even if Object Oriented Programming wasn't slow (it is), reading a OOP-heavy code base sucks because the logic is broken into little pieces and spread all over. Makes it hard to understand the system as a whole.
There is a difference between the inherent complexity of the problem you're trying to solve, and the artificial complexity you created by the way you wrote the code.
The whole point of OOP is to break up logic and data into lots of little objects and have them all talk to each other. So now you have to understand the logic of the problem you're solving AND the structure of all the objects you made.
For comparison: Data Oriented Design results in code that very closely matches the minimum amount of computation required by your problem — it doesn't layer on a bunch of unnecessary indirection.
https://x.com/DanielcHooper/status/1784983115196207425
What you get when you follow OOP properly:
- A bunch more code
- A bunch more complexity
- A whole lot less performance
What's the point of this ideology masquerading as an engineering discipline if it just makes your life harder?
https://x.com/falconerd/status/1788665267708690590
https://x.com/SebAaltonen/status/1848251209129275789
https://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html
- język dynamiczny vs typowany
- ręczne zarządzanie pamięcią vs odśmiecacz pamięci
- synchroniczne vs asynchroniczne: more coupled to less coupled: callback -> one value: promise, async/await, multiple values: observable -> channels
- indexing from 0 vs from 1
- https://pl.m.wikipedia.org/wiki/Architektura_wielowarstwowa
- "His view was that if a company tells you it is 'improving' the service it provides, it almost always means that it will be doing less for you, or charging you more, or both." https://en.wikipedia.org/wiki/Hutber%27s_law
- [RAII and the Rust/Linux Drama](https://kristoff.it/blog/raii-rust-linux/
- Replace RAII with batch operations
I would often find STL containers as the root of a performance issue, only to have to rewrite those segments of code to an optimised pure C equivalent.
There is nothing wrong with those containers, or their implementation, but they hide the dynamic memory allocation and de-allocation they carry out for you.
https://www.cowleyforniastudios.com/2025/1/20/choosing-c
- zakomentuj część kodu jak w wyszukiwaniu binarnym
- print debugging
- breakpoints i step-by-step, step-inside
- Heisenbug - np. w asynchronicznym programowaniu
- "Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?" Brian Kernighan, "The Elements of Programming Style", 2nd edition, chapter 2
- https://wiki.c2.com/?TestsCantProveTheAbsenceOfBugs
- TDD bad for exploration and research, awesome when fixing bugs
więcej o TDD
TDD is awesome when fixing bugs (as opposed to writing features), when writing straight up business logic (especially when there are a lot of edge cases) and when you know exactly how something is going to work.It's really bad when doing anything that requires exploration and research (which is the example in the article).
https://news.ycombinator.com/item?id=20976486
I work for a Danish municipality and we buy quite a lot of development from various software houses. Being the public sector we track and benchmark almost everything, and we actually have a dataset on automated testing that’s been running for two decades. It’s hard to use the data, because we’re comparing different projects, teams and suppliers but our data shows no advantage in choosing the companies that are very test-focused. They are often slower, more expensive but have the same amount of incident reports as the companies which tests less or doesn’t do automated test at all.
https://news.ycombinator.com/item?id=20976397
I'd take a slightly different take:
- Structure your code so it is mostly leaves.
- Unit test the leaves.
- Integration test the rest if needed. I like this approach in part because making lots of leaves also adds to the "literate"-ness of the code. With lots of opportunities to name your primitives, the code is much closer to being self documenting. Depending on the project and its requirements, I also think "lazy" testing has value. Any time you are looking at a block of code, suspicious that it's the source of a bug, write a test for it. If you're in an environment where bugs aren't costly, where attribution goes through few layers of code, and bugs are easily visible when they occur, this can save a lot of time. My leaves are either pure functions (FP languages) or value objects that init themselves based on other value objects (OOP languages). These value objects have no methods, no computed properties, etc. Just inert data. No mocks and no “header” interfaces needed. On top of that I sprinkle a bunch of UI tests to verify it’s all properly wired up.
https://news.ycombinator.com/item?id=15565875
I'm grateful for what TDD did to open my eyes to automated regression testing, but I've long since moved on from the design dogma. Test-first units leads to an overly complex web of intermediary objects and indirection in order to avoid doing anything that's "slow". Like hitting the database. Or file IO. Or going through the browser to test the whole system. It's given birth to some truly horrendous monstrosities of architecture. A dense jungle of service objects, command patterns, and worse.
- sposób Briana Fitzpatricka vs TDD
więcej o sposobie Briana Fitzpatricka
Seibel: Jak projektujesz swoje oprogramowanie?
Fitzpatrick: Zaczynam od interfejsów łączących poszczególne elementy. Identyfikuję typowe metody, typowe wywołania RPC lub typowe zapytania. Jeśli chodzi o składowanie danych, staram się określić najbardziej typowe zapytania. Oceniam, których indeksów będziemy potrzebować. Zastanawiam się nad strukturą danych przechowywanych na dysku. Później piszę uproszczone wersje poszczególnych elementów systemu i zaczynam je stopniowo rozwijać.
Seibel: Wykorzystujesz te próbki w roli testów (w myśl zasady: najpierw testy), aby w przyszłości testować rozwijane rozwiązania?
Fitzpatrick: Robię tak coraz częściej. Zawsze projektowałem oprogramowanie w ten sposób, nawet wtedy, gdy nie przywiązywałem wagi do testów. Zaczynałem od projektowania interfejsów i sposobu składowania danych, by następnie przystąpić do właściwej implementacji.
Seibel: Jaką formę przybiera taki projekt? Pseudokodu? Właściwego kodu? Bazgrołów na tablicy?
Fitzpatrick: Najczęściej po prostu otwieram edytor i sporządzam notatki dotyczące projektowanego schematu wraz z elementami pseudokodu. Kiedy projekt w tej formie osiąga stan, który mnie satysfakcjonuje, przygotowuję prawdziwy schemat oraz kopiuję i wklejam gotowe elementy kodu, aby mieć pewność, że przynajmniej wyrażenia create table działają jak należy. Kiedy już wszystko na tym etapie wydaje mi się dopięte na ostatni guzik, przystępuję do implementacji tak zapisanych koncepcji. Zawsze zaczynam od pliku spec.txt.
Seibel: Czy już po napisaniu kiedykolwiek odkryłeś, że musisz zrewidować swój oryginalny plan?
Fitzpatrick: Czasami. Zawsze jednak zaczynałem pracę od najtrudniejszych elementów lub od koncepcji, których nie byłem pewien — te elementy implementowałem w pierwszej kolejności. Staram się nie odkładać na ostatnią chwilę tego, co najtrudniejsze lub najbardziej zaskakujące; lubię zaczynać od najtrudniejszych aspektów. We wszystkich projektach, których nigdy nie skończyłem — moi znajomi zarzucają mi, że była ich cała masa — faktycznym powodem niepowodzeń było właśnie rozpoczynanie prac od najtrudniejszych elementów, odkrywanie, że muszę się czegoś nauczyć, i ostateczna rezygnacja z realizacji najbardziej nudnych aspektów.
https://lubimyczytac.pl/ksiazka/101063/sztuka-kodowania-sekrety-wielkich-programistow
- https://exercism.org/
- https://leetcode.com/studyplan/
- https://x.com/NeetAcc/status/1828059231120961655
- https://x.com/NeetAcc/status/1828111694616559719
- sen, odpoczynek, skupienie, podnoszenie ciężarów/kalistenika/sztuki walki
więcej o zdrowiu
One of my most controversial software opinions is that your sleep quality and stress level matter far, far more than the languages you use or the practices you follow. Nothing else comes close: not type systems, not TDD, not formal methods, not ANYTHING.
https://twitter.com/hillelogram/status/1119709859979714560
By reanalyzing the data, she and her colleagues made two key findings. First, they found that the volunteers’ performance improved primarily during the short rests, and not during typing. The improvements made during the rest periods added up to the overall gains the volunteers made that day. Moreover, these gains were much greater than the ones seen after the volunteers returned the next day to try again, suggesting that the early breaks played as critical a role in learning as the practicing itself. Second, by looking at the brain waves, Dr. Bönstrup found activity patterns that suggested the volunteers’ brains were consolidating, or solidifying, memories during the rest periods. Specifically, they found that the changes in the size of brain waves, called beta rhythms, correlated with the improvements the volunteers made during the rests. Further analysis suggested that the changes in beta oscillations primarily happened in the right hemispheres of the volunteers’ brains and along neural networks connecting the frontal and parietal lobes that are known to help control the planning of movements. These changes only happened during the breaks and were the only brain wave patterns that correlated with performance. “Our results suggest that it may be important to optimize the timing and configuration of rest intervals when implementing rehabilitative treatments in stroke patients or when learning to play the piano in normal volunteers,” said Dr. Cohen. “Whether these results apply to other forms of learning and memory formation remains an open question.” Dr. Cohen’s team plans to explore, in greater detail, the role of these early resting periods in learning and memory. https://www.ninds.nih.gov/.../Want-learn-new-skill-Take...
via https://news.ycombinator.com/item?id=19661949
Remote work taught me that working in batches can really drive up my efficiency. 2.5 hours at the start of the day, a half hour break, then another period of work about the same length, and then finally one more. I find this breaks up things and allows the 'down time' to settle in my head so I can come back and prep to get "in the zone" for another two hour purely focused work period. All that ties in wonderfully to his routine keeping, which is a great template to work with. It helps to shut off all notifications on your phone or computer as well, including email.
some of the core tensions in software engineering:
- dev effort vs performance
- never crash vs fail-fast
- boilerplate vs hidden magic
https://x.com/gpu_thief/status/1951382019407319543
Exception handling is one of these mountains of abstraction. It turns operations that are very fast into operations that are slow (and also slows down the entire program by imposing the constraints required to successfully throw exceptions.)
https://x.com/Jonathan_Blow/status/1951379464400806058
- Make errors values
- Require handling errors
- When you do both it makes code clearer, no hidden control flow
https://x.com/canoozie/status/1951520794611155230
The Ontic @tautolog
The problem is that exceptions make errors not a part of the interface. You write a consumer handling one set of exceptions, then a new exception is introduced by a new feature. The consumer breaks. This is why errors are values.
Dr Whopper @BKAngryKing
Claiming errors are values in that scenario does nothing to address the problem of introducing new error states... exceptions handle new error types very elegantly...
The Ontic @tautolog
You are seeing them as the same one level deep. Consider multiple levels. When errors are values, the values are reconsidered at each level. You can do that with exceptions, but that is considered an anti-pattern, so unknown errors will raise into higher level libraries.