Comments by "MrAbrazildo" (@MrAbrazildo) on "Continuous Delivery"
channel.
-
7
-
5
-
4
-
5:13, C++ 3x1 Java (2,7x1, actually), according to a test at Dave's Garage, another ex Microsoft: https://www.youtube.com/watch?v=D3h62rgewZM&t=1342s , if you consider C# is about the same speed as Java: https://www.youtube.com/watch?v=sJC3JsvhM9o&t=1203s .
5:35, + C++ also gives you more control over the design too, allowing to make better tools, even for defensive proposes. I heard in a presentation that C++ is also used in "secure critical systems", or something like that. I'm not a bit surprised. I coded my own boundaries checking for any container, and never again had a problem about that that wasn't reported properly.
5:49, Mike Acton about this for his HPC#, an attempt to make C# the new C++: https://www.youtube.com/watch?v=u8B3j8rqYMw&t=872s .
3
-
10:15, for me this would be an annoyance only if I was making it for free. As an employee, it's ok.
16:09, I thought you would say: less code, smaller changes. Well, it seems that pair programming does that, in a speaking way.
17:25, but that would not mean that 2 individuals, working in parallel, produce in 42.6 minutes what pair programming would take 30*2 = 1 hour?
17:28, I have none of these problems.
3
-
11:40, I use to think the general flow of data as a simple thing. But in practice, some ugly measures have to be done. Splitting classes to keep data security, more layers of data access to become clear, and so on. All things that I rather not do, but technically I feel compeling to.
People discuss how much inheritance can mess things up, but I don't use to have such issues: I start with a simple thing, focused on what I need now, and throughout time I come back to make little upgrades. It's a kind of "become forced by practice" motto.
13:15, there's a problem in multithread, called "false sharing": each time a process read a cache line (32 or 64 bytes), it blocks to all other threads the access to that line (those bytes). To solve this: put data from each thread in different cache lines.
17:20, someone said, in a recent presentation: "Classes work as black boxes: we put things there and forget about it" . I appreciate this in design: the less 1 needs to keep in mind, the easier it will be to upgrade the architecture.
3
-
4:20, I can't even remember if I ever had a serious bug using pointers. Here go my tips for everyone, who use to have problems with that, to get rid of this issue once and for all:
- If you have to allocate memory, don't do that directly: use containers from the standard library , STL. They have their size hidden from you, and manage it automatically.
- When traversing those containers, use their own iterators (OO pointers). Member-f()s 'begin' and 'end' provide them for you. Just keep a model like this:
for_each (container.begin() + offset, container.end() - premature_end, some_algorithm);
With offset <= premature_end, and both >= 0. If you just want to run all the way (default is copy, but you can reference that, with &) :
for (auto &a_var_not_ptr: container) some_algorithm (a_var_not_ptr);
In any of these cases you deal with pointer directly.
- Reallocations may invalidate previous iterators :
std::vector <Type> container;
auto it = container.cbegin() + K;
container.push_back (M); //May invalidate.
auto x = *it; //May crash.
There are 2 main solutions for this:
a) Just "refresh it", after push_back:
auto it = container.cbegin() + K; // ≃ F5 in a webpage.
auto x = *it; //Guaranteed to work.
b) Recommended: reserve memory right after container creation:
//Chandler Carruth: "We allocate a page each time. This is astonishing fast!"
container.reserve (1024);
container.push_back (M); //Just added M, not reallocate.
auto x = *it; //Ok.
There won't has a new reallocation, as long as container.size() <= container.capacity() . This is much faster and generates a much shorter bytecode.
- If you need to allocate directly, use smart pointers instead, to do that for you on the backstage - as well as free them.
- If, for any reason, you need a C-like pointer (raw pointer), wrap it inside a class , together with a variable for its size, both hidden (no Java setter methods!) and a destructor, to automatically free the memory of a specific object, once that specific object ceases its existence.
- In this case, you will have to write a copy constructor for it, to avoid "memory stealing" , from 1 object that has copied its content, and had its destructor activated.
If you already wrote that class, and are in a hurry to use it before writing this constructor, you can still be safe by temporarily deleting its attribution operators (each_of_their_declarations = delete): if any copy is made, it will arise a compile-time error .
- I read on GCC (compiler) documentation, that the OS may not provide a pointer aiming before the container . So, if you intend to use reverse iterator, keep that in mind.
- Just like index, pointer keeps its step as large as the size of the type it's pointing to. I once had a code running on Windows and Linux, both 32 bits, using 24 bits (+ 8 bits alpha) BMP images. They were read by pointers of type 'long', the max/platform size, to keep portable for the future, automatically growing up to pixel size and OS.
When I migrated to Linux 64 bits, it started to get unstable on Linux only. It took me a couple of minutes to figure it out: pointer step became twice the intended size. Easy.
- Let's say a f() received pointer for object of class 'animal', and it accesses also the 'dog' class supposedly in it, a class that inherits animal. But this may be just a pointer to 'animal', not dog + animal.
To make this downcast, use dynamic_cast: it makes a runtime check , to see if there's "ground for pointer landing".
- Above all things, watch out for undefined behaviour . 1 of the many tricks C++ uses to get faster is to not bother the compiler, about the order it must execute things. There's operator preceding, but if that is respected, any order is accepted. So, don't do messy things like this:
pointer[index++] = ++index*5;
Sure, it will execute [], multiplication, =, those 3 in this order. But what index it will treat 1st? You must get used to have a special look for too compacted commands. Instead of that, unroll the command in the order you are thinking (read-only instructions are 100% safe, even for multithread) :
++index; pointer[index] = index*5; index++;
======= // ===========
This is about all the universe of a pointer, all tricks it might trick on you. If you keep yourself lucid about those topics, each time you deal with pointers, they will never be more-than-minutes-to-solve bugs for you.
PS: pointer is much faster than index, because it memorizes "where it is", meanwhile index goes all the way from the begin, each time it is called .
2
-
2
-
2
-
2
-
2:00, I disagree, because nowadays every command does many things. For instance, if you are searching something in an array, you can put a comment not the kind of "finding something", but for why are you searching that - not technically, but semantically. 2:30, here, I would write a comment about what is 'r', and why it's calculated like that. And I would do that at the right of the line, to avoid growing it downward. 3:45, I think it's not always possible: sometimes it's too intricate, and you will want to break it in parts, even harder to explain.
4:25, a majority of my f()s can be seen entirely in 1 screen. However (6:03), there are some of them that take 3 or more. And their content works as something private, that should not make sense to be exposed to the rest of the project, in a form of other f()s. Of course I'm not talking about reusable things (7:07), but about only 1 goal (7:55) that requires many steps, many initializations, many private and temporary data.
2
-
2
-
2
-
0:23, ahahhahahah! What's this, stand up comedy?! Java should be vanished for good! 3:08, which keeps being right... 3:38, a bad idea. Destructors can handle this automatically. The only tiny price is that you understand the concept of scope, the life cycle of a variable. A Microsoft employee once said in a presentation, about automatizing a task that you need to remember, once a variable cease its existence: (C++ creator) "Bjarne solved this problem, but the world keeps acting like if it wasn't" .
6:19, C++ has that too. It's called profiling (the code). Compilers have a flag for that, turned off by default.
6:35, "C++ is the language of choice for trading systems: it has high level abstractions, it's flexible, can make solid and fast tools. That's what we need" , said a trading systems employee, in a presentation. "We can do a trade faster than the light traversing upside down the tallest build!" .
8:42, maybe C#. But Java is simply awkward. They thought that the 'friend' keyword from C++ was a mistake, and removed it. Result: the setter methods expose private content. This is a shot at programmer's head! Java is anti-design!
9:55, yeah, he removed the knifes from the kitchen.
11:05, well, you can do that mess with C++: pile classes, 1 above the other, like some kind of t**, and then you go: houston.we.have.a.problem.there.is.no.decoupling()
2
-
2
-
2
-
2
-
7:30, I use tab = 2.
9:10, what is xPathString? You just deleted the comment. 10:15, don't delete, just put it at the right side. 11:00, mm... I wouldn't do that. 11:11, omg... I know Java is awkward, but the comment was saying where things were placed. 13:52 and 14:01, somebody put this man in jail! :)
12:25, I would permanently highlight the 'hasChildren' 1st, or if this doesn't exist in the IDE, I would use the find recurse, to spot every occurrence of it.
12:45, "equal to" and "has it" are 2 different things to me. That's why I would not delete the comment.
- Here's the proof of a DRY violation: there's the hasChildren f(), but the programmer forgot it, because the previous f() was too big.
- 13:17: at least in compiled languages, deleting (safer: turning it into a comment, actually) getXPathString() would reveal all calls to this "f()".
How C++ is elegant compared to this s**! You could write:
11:20, jsonString += Str1 + Str2 + ... StrN.
13:00, return jsonString.substr (blabla) + "]". Period!
13:40, String tagetString = shortXPath.equals("") ? "//toc" : "//".
2
-
2
-
5:30, true: if it is C++, approved; if not, we will use it by force! :)
7:50, depends on the skills of those people. Plus, the communication will has a growing challenge.
10:10, depends on how desperate is that deadline. Plus, deadline is kind of an absurd concept. About refactoring, I think is recommended to do it till certain point, when you feel things won't fall apart anymore, due to the lack of it.
12:12, for a team, I guess it's the communication. If working alone, coding skills.
15:00, true, we have C++, and it is still not able to solve things for us - it only give us the right tools.
2
-
2
-
2
-
2
-
2
-
2
-
1:10, Java IS very nasty code!
8:40, I didn't get it: it still has the breaks. How passed this time?
14:12, I think you make too many f()s. Some thoughts about that:
1) Whenever you extract a f(), you are putting related things a bit away from each other, and a bit near to the rest of the outside code. This also can lead to accidental calls to those f()s. /*Edit: and you'll deal with more code.*/
2) Compilers use to inline a certain amount of f()s. And if you raise that number, it can eventually get an unnecessary extra large generated byte code. This can lead to slowness.
3) 13:13, as I said on the previous video, for C++, just: return jsonString.substr (blabla) + "]" , which would be 1 line, no extra f(). But I guess Java is too bad to has that.
2
-
@plan.b2 Let's say you want to hide data in C, kind of a class in C++. You will have to put that data aside, in other file, to be seen only in that file, with some f()s to talk to public. And how could you inherit this code? You could repeat it with macros, but it would be awful, because of too many code. I love macros, but not for an entire class.
And let's say you want several objects of that "class" in C. There's no way, unless you transform all from that file into arrays, but the resulting code would be prone to errors, compared to a C++ array of objects.
2
-
2
-
2
-
2
-
@plan.b2 The DRY principle (Do not Repeat Yourself) protects the coder from errors. Inheritance works with it. Let's say you must compute objects and people. Both have locations, and you want compress locations coordinates to save memory, leading to not intuitive code. It's nice to have that in a class, with f()s to unpack info behind the scenes and keep a higher level dialogue. Both classes inheriting that is DRY.
Even if you use hash table, trying to say that won't inherit, because it will be an unique array/list/container, you can reach a situation in which you realize it's better to have 2 hash tables, because let's say, people is the "hot data" (more accessed), and the whole app will be faster if accessed separately. In this case, the locations class could hold an array itself, being inherited by both hash tables, keeping the DRY principle.
2
-
8:17, once I had a serious 8-days-to-catch bug (more than 1 day for me is rare), the longest in my life, as long as I remember, due to using explicit number instead of a word representing it.
10:50, from a technical point-of-view, macros could reduce this code nicely. And I would not switch a String, I would use numbers instead (global named constants), which are way faster and safer, if you consider case-sensitive and other tricky strings pitfalls. And I would not 'throw' anything, which is slow and gives nothing in trade.
2
-
1
-
1
-
I guess by now everybody understood TDD is good. You should now become more technical. Let's say I have a f() that makes several steps to reach a goal. It has several steps because they are private to it, they would not make sense outside of it - it could be prone to errors if called outside . And that f() also updates variables in other classes, because otherwise this should be scheduled to do later, and before some certain other actions take place - and would be prone to errors too, if this schedule fails to complete or, in worse cases, fails to follow a certain order too . By what I understood so far, TDD would demand that a f(), which would be written like that, be splitted in several small f()s. So, to avoid a disaster, I think 2 possible solutions:
a) Each f() like this should become a class, with all those private steps being private f()s from it. Tests would have plenty of access to those f()s, most of them not tagged as 'const'. Fortunately, tests are small, and compile-time prone to be implemented. So, tests are unlikely to cause bugs - and easy to fix if that happens.
Pros: each test would be executed only 1 time .
Cons: kind of a "risky" design .
b) Any f() like this stays the same, but its steps could become lambdas, in order to be tested, and this would be made inside that "big f()", each time anyone calls it. To avoid repeated tests execution (hence consuming performance), they could only communicate in case of failing. Since they are compile-time (according to your examples), the optimizer could solve them, realizing that they work, meaning they would do nothing, and then it could decide to eliminate them at compile-time, "because they are useless" (unreachable code). For the tests that accuse an error, the programmer should fix them right away, in order to them become potentially "useless" too - thus eliminated too.
Pros: design continues to be as safe as before, despite tests intrusion .
Cons: tests would be processed several times, unless the optimizer decides to wipe them out .
1
-
1
-
1
-
1
-
Thumbs down for this obscenity, of course.
2:17, nothing can piss off more a developer than a company trying to make $$ with his project, offering nothing. I totally understand. What was its license? 2:47, yes, but that doesn't mean you are willing to work for free - or even in a cheap way.
4:06, I wish him success on this.
5:07, this definition is wrong. The world is not free, so software is not too. The idea is to keep it free as long as it is not used to make $$. 6:24, nobody wants to work for free, when life has its costs. This is slavery. 7:15, neither the creator nor (and much less) greedy f** companies! 7:29, you are being hypocritical: you are maliciously turning an altruistic work for knowlegment and reputation into slavery. An open source movement would never exist if that was the idea.
8:16, let's dive into piracy, clone all apps. They show us apps, so better they be lucky trying to make $$ out of them. 8:35, he was naive to not read the GitHub license, which allows anyone to put his/her own license over the creator's, once he/she modifies just a bit of the original project . Thus, I decided to not put any work of mine there - and never will.
14:07, for the last time: he was not expecting $$, he just not wanted to be turned into a slave! But he was too naive to not had read the evil GitHub license.
1
-
1
-
I'm more of a mercenary-mind about software: $$, no deadline and a decent language are pretty much all that matters.
My thoughts about the questions:
10:45, 1st: I don't care. 2nd: Even the worst boss would not make any difference, if he "doesn't get in the way". 3rd: I don't care. 4th: I don't want to go to a conference. 5th: I don't care.
11:55, I don't care about all of that. I could alert them, but it would be all. I would not lose any sleeping night.
12:55, 1st and 2nd: I don't care. 3rd: I had those 3 goals above. The rest is garbage collected. 4th: I'm not excited to achieve anything, working to anyone, much less for a $$ hungry company. I don't "fall in love" for this work anymore. But that doesn't mean I would not fight for the company's goal - unless that was something evil, like censorship, privacy invading or something alike .
15:15, if the company wants to blow itself down, what can I do? I would try do advise, though.
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1