dennisgorelik: 2020-06-13 in my home office (Default)
2019-03-25 02:32 am

Code reuse

From 11 years of maintaining my own codebase I learned that reusing fields is a bad idea that leads to poor code maintainability.
If unrelated methods use the same fields, then graph of field references start looking like a maze that is very hard to understand.
If "UserId" field is called by 19 methods from at least 2 distinct logical groups, then it takes long time to find out if we still need to load UserId from database record in JobAlertRequest().
If count of UserId references was much lower, then such review would take much less time.

Reusing fields (and local variables) is, generally, bad for maintenance.
But reusing methods is, generally, good for maintenance: if we fix bugs in a reused method - all places that use functionality are getting fixed.
dennisgorelik: 2020-06-13 in my home office (Default)
2018-10-29 04:46 pm

Code review

In our team we do code reviews a lot.
We code review everything: C#, SQL, ElasticSearch, XML, HTML, javascript, powershell, linux shell scripts, and manual installation instructions.

The main reasons to do code review:
1) Knowledge exchange
- Code reviewer learns from code he reviews.
- Coder learns from code reviewer's feedback.
- All team members learn from code review discussion.
2) Bug fixing
Code reviews detect a lot of bugs (before they damage our production environment).

We do code review multiple times per single commit:
1) Developer reviews diff of his own code before he makes his original commit.
2) Code reviewer reviews commit.
Single commit may have several code reviewers (if several developers on our team consider that commit to be relevant to their interest).
3) In the future, when we maintain our code (need to extend or fix a bug or just recall why code does what it does) -- we do svn blame for line in question and review commit again.

Because code review is so important and because we do code review multiple times -- we try to optimize code commit for code review.
That means we try to minimize time that is needed for code review:
1) We try to write clear "commit comment" explaining the purpose of each commit.
2) We try to reduce the size of individual commit.
That means - commit separate features in a separate commits (do not mix multiple features in a separate commit).
We commit refactorings (that we need to do in order to correctly implement feature) separately from actual feature implementation (it is much easier to review code diff if you know that this code is only a refactoring did not change functionality).
We try to separate refactorings from each other too.
It is much easier for code reviewer to understand smaller commits.
Smaller commit size is also easier to explain in "commit comment" (what is the purpose of that commit).
3) We understand that it is OK to spend more time on coding and explaining commit -- in order to reduce code review time.

---
Inspired by I hate code review discussion on Hacker News.
dennisgorelik: 2020-06-13 in my home office (Default)
2018-05-25 05:16 pm

Inconsistent .NET Framework behavior

Several days ago Microsoft released new update to Windows 10.
That update changed how this code works:
new Uri(baseUri, relativeUrl)

The difference is in how this code works in case if baseUri is malformed.

Prior to Windows 10 update this code crashed with System.NullReferenceException
After the update -- the same code no longer crashes.
[Test]
public void CompatibilityTest()
{
	Uri baseUri = new Uri("https://jobs.web.cern.ch/content/cern-jobs-insight/what-are-we-doing-while-you%E2%80%99re-waiting");
	const string badUrl = "https:/jobs.web.cern.ch/content/cern-jobs-insight/what-are-we-doing-while-you%E2%80%99re-waiting";
	var result = new Uri(baseUri, badUrl);
}

Note malformed "https:/" in badUrl.

Currently my Windows 10 machine has .NET Framework 4.7.03056 [1]
With the most recent Windows 10 update this code successfully puts into result variable:
---
https://jobs.web.cern.ch/jobs.web.cern.ch/content/cern-jobs-insight/what-are-we-doing-while-you’re-waiting
---

However on Windows Server with .NET Framework 4.7.02053 the same code crashes with NullReferenceException.

What do you think is the correct behavior for malformed baseUri input: try to guess correct baseUrl path or crash with NullReferenceException?

My guess is that Microsoft finally decided to properly fix this "malformed input" bug (and not longer crash).
If my guess is correct - then in the following versions of .NET Framework this NullReferenceException crash would disappear even on Windows Server platform.

----
[1] You may determine what .NET Framework version installed by running regedit:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full

... or by opening: Visual Studio - Help - About Microsoft Visual Studio

[2] .NET targetFramework mess
dennisgorelik: 2020-06-13 in my home office (Default)
2018-05-06 03:27 am

Breaking down hard problems

With experience I learned breaking down problems into parts.
Tom Stuart verbalized that in his insightful presentation: The Most Common Problem In Software Development And How To
---
2:00 - A large task, all in your head.
3:12 - The symptoms
...
6:55 - It takes a long time to pick up your thread again.
...
18:18 - Make small, focused commits
18:27 - Write commit messages that explain your thinking.
21:26 - Cherry-pick preparatory work onto master.
23:46 - Practice switching away.
29:00 - Write tests that really do check what you care about.
30:45 - Practice explaining your train of thought.
33:01 - The overall technique of approaching the way that you work on big things: "Notice the risk, then break it down."
---
dennisgorelik: 2020-06-13 in my home office (Default)
2017-07-25 11:28 am

Software development - constantly balancing problems against each other

Short names vs unique names
It is a good practice to use shorter method names, because long names are harder to read.
It is cleaner to call:
candidate.Save();
than:
candidate.SaveCandidate();

But then we end up with multiple "Save()" methods in different classes. For example:
Candidate.cs/Save()
Recruiter.cs/Save()

Problem with non-unique names
If we search our codebase for "Save(" - we would find a lot of methods and method calls. Only some of them would relate to the functionality we actually want to research (for example, we may want to research where "Candidate Save()" functionality is used because we consider refactoring or deleting it).

Plain text search vs code references
Visual Studio allows to find all references to a specific method by right-mouse-clicking on a method name and selecting "Find All References".
So, non-unique method names problem is solved, right?
Not quite.
Visual Studio is not able to track method calls that are made from aspx and ashx files.
Visual Studio is also not able to find method references in the comments.

ReSharper vs vanilla Visual Studio
ReSharper actually is able to find method references in aspx, ashx and even in comments. Until Visual Studio 2015 that worked fine. But since ReSharper team and codebase aged, and Visual Studio switched to new Roslyn compiler, ReSharper team was not able to keep up and delivered only barely working resource hog, that is practically not usable with newer version of Visual Studio (too slow).

Get rid of aspx and ashx files?
It is actually pretty easy to avoid using ashx handlers and use standard C# classes to implement HttpHandler interface.
But what about aspx pages: can we get rid of them too and use only standard C# HttpHandlers?
If we could do that, then we would be able to rely on "Find All References" feature again.
But, unfortunately, getting rid of aspx pages is not that simple. We would have to reimplement a lot of functionality that aspx has.
For example:
- Page PostBack support would be gone.
- Ability to nicely combine HTML code and aspx controls alongside each other would be gone.
- HTML syntax validation would be gone (no HTML syntax validation for C# strings in Visual Studio).

If it ain't broke - don't fix it
Even though it is pretty straightforward operation to convert existing ashx files into standard C# classes (where Visual Studio is able to track all method references) - such conversion is not without its own problems.
- Conversion takes developer's time.
- Code replacement could introduce silly bugs.
- Moving code from class to class makes navigating "svn blame" - a little bit trickier.
So if an ashx handler was working in the solution for many years already - does it make sense to touch it now?

The benefits of code refactoring
In spite of "If it ain't broke - don't fix it" rule - cleaning up code is still needed. If we do not keep code clean (do not delete unneeded parts and do not clear confusing things such as hidden references) - then our codebase would be extremely hard to maintain. Fixing a bug would introduce other bugs. Features would be very hard to add without adding bugs.

It depends
There is no single solution that can be applied to all situations. In software development we consider multiple problems and constantly weigh pros and cons against each other.
For example, out of 11 remaining ashx files, we:
- Deleted one file because we do not use it ("Reduce amount of code when possible" principle).
- Would migrate one file to the standard C# HttpHandler, because today during refactoring a developer missed a method call from that ashx file.
- Keep other 9 ashx files as is ("If it ain't broke - don't fix it" principle).

What are your examples of balancing problems against each other?
dennisgorelik: (2009)
2016-02-03 03:11 am

Heisenberg Developers

This is good explanation of why too detailed software development plans for do not make sense.

----
http://mikehadlow.blogspot.cl/2014/06/heisenberg-developers.html
The problem with this approach is that it fundamentally misunderstands the nature of software development. That it is a creative and experimental process. Software development is a complex system of multiple poorly understood feedback loops and interactions. It is an organic process of trial and error, false starts, experiments and monumental cock-ups. Numerous studies have shown that effective creative work is best done by motivated autonomous experts. As developers we need to be free to try things out, see how they evolve, back away from bad decisions, maybe try several different things before we find one that works. We don’t have hard numbers for why we want to try this or that, or why we want to stop in the middle of this task and throw away everything we’ve done. We can’t really justify all our decisions, many them are hunches, many of them are wrong.
----

Discussion on HN: https://news.ycombinator.com/item?id=11024656
dennisgorelik: (2009)
2015-10-29 08:41 am

The root cause for 2 days of troubleshooting

Yesterday Priya could not extract file from our HTTP POST request.
Today we found out why.

See below the highlights of our email discussion.

Dennis:
Priya,

Could you please cooperate with us on what I and Andrey requested from you?

You already refused Skype session with us.
Skype is the fastest way to resolve technical difficulties like that.

But if you are not able to troubleshoot your environment issues with us over Skype - please at least send us what we asked for:
- Code snippets (Indeed Apply resume file extraction vs PostJobFree request file extraction).
- Value from $post['resumeData'] variable you are getting from PostJobFree request.

Priya:
Sorry about my Skype, I normally do not get online unless very emergency since its very distracting, but I tend to check and reply all emails received I hope you agree.
...

Please see attached
1. the resume after save
2. resume content from post before save
3. post data raw, two versions, without xss filter and with xss filter
4. indeed apply
5. postjobfree apply

Dennis:
Priya,

1) Thank you, that clarifies what is happening in your system a little.

2) candidate_post_raw.txt contains only part of resumeData (about 70% of original resumeData listed in http://requestb.in/xfzso4xg?inspect ).
...

Andrey:
Priya,

I already tried to post resumeData to your prod endpoint few hours ago

Priya:
yes, I found it, and it works :)
see attached, please send some more so I can validate

Dennis:
Priya,

Good.
The attachment looks correct.

So what was the root cause for the problem?

Priya:
It seem I had a copy paste issue on requestbin, the main logic was in place and no change required actually
dennisgorelik: 2020-06-13 in my home office (Default)
2011-05-19 08:45 pm

(no subject)

My take on how to handle users permissions in software application:
Role-based permissions vs. Enterprise permissions

Use shorter "Users-Roles-Features" mapping instead of enterprisy "Users-Groups-Privileges-Features" mapping.