Everything I googled in a week as a professional software engineer
localghost.dev
localghost.dev
ln -s a b
then look at the link with ls -l, then remove my garbage!
Your way is much better. ln -s ../../a_fine_file .
With the added '.' at the end. That way, I can remember to change the period out if I don't want the same name (or if I'm linking in the same directory).The real question I have left: why is this so intuitive for cp, but completely counterintuitive for ln?
I wonder if is because we think of how we would follow the link.
That doesn't make sense to me. The way I think about cp is "copy this, and put it over here". If you think about symlinks that way, you mix it up.
When you say "source to destination, where destination is the soft link", that makes it more confusing for me, because if you consider the symlink that is being created as the "destination" (which at least is the intuitive way to think about it for me, but I suppose it's individual), you actually end up with:
# cp [source] [destination]
# ln -s [destination] [source]
Where "source" is "the new thing that should be created".
Since I seem incapable of getting out of this way of thinking about sources and destinations, my rule of thumb is that when creating a symlink, you always decide where it should point first. Not intuitive perhaps, but this time I've made the mistake so many times it kinda sticks.
ln /some/file /other/file
/some/file and /other/file are hard links. So in this case ln is just copying a hard link, while afaik cp would be copying data, making a hard link pointing to the new data. In userspace? That seems to be what's happening here - https://github.com/openbsd/src/blob/master/bin/cp/utils.cThis is made a bit more confusing by the differences in man pages. For GNU ln, it's shown as ln TARGET LINK_NAME, but for OpenBSD, ln source [target]. But the usage is pretty much the same?
# cp [existing-thing] [new-thing]
# mv [existing-thing] [new-thing]
# ln -s [existing-thing] [new-thing]
Remember it like this: It's the same syntax as "cp". To copy a file you use "cp source dest". It's the same for ln: "ln -s source dest"
The association with cp makes a lot more sense then. This is how I learned it.
softlink dest <- src
file cp src -> dest
std::memcpy dest <- src
java arraycopy src -> dest
golang io.Copy dest <- src
etc etc
I'm only 80% confident I didn't make an error in the above 5 examples...
AT&T assembly: mov src, dest
Whenever I'm debugging at the assembly level I have to just write down the appropriate one on a piece of paper in front of me.
Mnemnic that helps me: IN SYMLINKS, REAL FIRST!
ln -s REAL_FILE link_name
1. Same as mv: `mv REAL_FILE link_name`
2. The second argument is optional. Therefore, the first argument must be the real file, and the second the link name. It does not make sense to omit the real file.
"Source" and "target" are confusing names because the target of the ln command is the file it creates, which is the symlink that points to the source file, which is the "target" of the symlink in an intuitive sense. The mnemonic works because it matches mv and in that case the file that exists must obviously come first. In ln without -s the file also must exist, which makes perfect sense. So it's easy enough to remember if you understand what the ln semantics are and don't get hung up by the source and target jargon.
You're probably going to notice the time you spend reading man pages, when you just! want! to! get! something! done! And that's frustrating. What you're less likely to notice is the next five times you reach for the wrong tool, or have to go hunting around for some bubble-gum-and-twine way to do something, because you didn't previously read the man page that tells you exactly what you needed to know to do it easily and correctly.
Hell, I often find that while the author has managed to cram everything and the kitchen sink into it, there's so much missing from it regarding how a tool works, caveats, whatever. All these things that are crucial to actually understanding the tools you're using beyond what some flag or other does on a surface level.
Its one of those things that after almost 20 years, I should remember. But it just does not go in.
It becomes interesting when junior programmers are watching how I do something and I end up googl'ing things that they know.
I use the excuse that it fees up more space for other more interesting stuff, a bit like some execs just ware T-shirt and jeans to reduce the number of things to distract them in the morning so that can concentrate on the important things.
I see you take a similar approach to spelling
ln, cp, mv, most everything will always follow this pattern.
https://www.gnu.org/software/swbis/sw.html#o-Explicit-File-D...
$ tldr ln
ln
Creates links to files and directories.
- Create a symbolic link to a file or directory: ln -s path/to/file_or_directory path/to/symlink
- Overwrite an existing symbolic to point to a different file: ln -sf path/to/new_file path/to/symlink
- Create a hard link to a file: ln path/to/file path/to/hardlink
touch <destination...>
$EDITOR <destination...>
mv <current...> <destination>
cp <current...> <destination>
scp <current...> <destination>
mount <current> <destination>
The place you're putting something is last in each case; we can even include everything that doesn't modify its location.All I can think of that breaks the rule is `rm`, `unlink`, and `umount`. But they're hardly gotchas, and they're not reversing arguments they just don't have a 'destination'.
You can also do that with cp and mv if you need to, using `-t`. `cp -t .dotfiles/ .nanorc .bash*`. Generally more useful when you want to move a bunch of files around.
Zip does indeed break the 'rule', but this is not an excuse, cp and mv manage just fine with:
in in in in [...] out
Which is why I said the 'last' rather than 'second'.Right now my main battle is deciding to port docs like this into asciddoc(tor) or keep them in org, both being exported to html5 eventually.
Usage: ln [OPTIONS] TARGET... LINK|DIR
Create a link LINK or DIR/TARGET to the specified TARGET(s)I'm honestly surprised about the help confusion though:
ln --help Usage: ln [OPTION]... [-T] TARGET LINK_NAME (1st form)
For GNU ln at least I don't find it confusing at all particularly considering the only other option is LINK_NAME. I guess YMMV though and it seems kinda pointless to argue whether it is or is not confusing. Perhaps a poll could quantify it.
ln -s /the/real/thing
will create a symlink in your current directory with the same name.ln -s physical virtual
I never forgot it and can see it visually in my mind. You need something physical before you can virtualise it.
$ mv existing_path new_path
$ cp existing_path new_path
$ ln existing_path new_path ln -s src dstReal is always better than fake, real comes first.
Also, an obligatory xkcd: https://xkcd.com/1168/
This is not to criticize - we all have places our mental models break down unexpectedly. I'm just interested in how that's happening.
This has to exist... but that doesn’t.
Read it somewhere long time ago, never had to look for it again :)
It comes in the form of "go ahead and install this thing, and throw this config value into it, and it should just work". And my reaction is "I want to read up on that thing first. I want to know what stuff it writes to my computer and where and what paradigms it uses. I want to think about how it will best integrate with the tools and workflows we have already. And then once I've done that, I'll probably be able to move forward with it comfortably. Then I'll want to document it so it becomes part of the regular setup others do when they onboard onto the project."
Just this past week when I said a version of this, I got a reaction like there is something wrong with me.
Here is an actual single search progression for me (In reverse order because copy/pasta :shrug:
react context optimize rerender "props.children"
react context optimize rerender
react usereducer dispatch async
react usereducer dispatch api
usecontext usememo
optimize usecontext react
usereducer rerender usecontext
usereducer rerender
when to use usereducer
react hooks usecontext and usereducer
This is a fairly simple search, too - no use of negative search terms and minimal use of phrase matching. I didn't see any of those enhancements used in the OP which seems odd.
edit - formatting
Example: site:news.ycombinator.com -inurl:item google operators
site:news.ycombinator.com -site:news.ycombinator.com/item
In the above example, I would probably filter out results having to do with other react hooks so adding `-useState` would help accomplish that. If I am googling specific syntax or an error log, then wrapping it in quotes will do a phrase match and filter out results that don't contain the phrase.
I don't use the `site:` search pattern because just adding `github` does a good enough job and
Another pattern I use is `filetype:pdf`
:thinking: and lastly I nearly always use the tools to filter by results within the past year. That does an okay job filtering out older documentation, tutorials, articles etc
Edit: also `site:stackoverflow.com ruby "Hash#dig"` if you wanted an exact match, etc..
“word”
Verbatim phrase match:
“some phrase”
Verbatim word negation:
-“word”
Verbatim phrase negation:
-“some phrase”
The author states : What I’m trying to show with all this is that you can do something 100 times but still not remember how to do it off the top of your head.
My experience differs from this, if I were to rewrite it I would say something like:
"You can do something 100 times, and as long as you can look it up somewhere, it is okay to not memorize how to do it."
You have to evaluate the impact on your flow of stopping to look something up, you have to evaluate what you consider your 'base' skill set is to evaluate if you should memorize something.
Before Google, the canonical case here was arithmetic. Who needs to memorize multiplication tables if you have a calculator handy to do simple arithmetic. Basically if you cannot do basic arithmetic in your head, you are always going to be at a disadvantage with respect to someone who can.[1]
I have found a reasonable compromise, when I Google something like this, I write down the solution in an Evernote notebook that I keep for such things. So if the same question comes up I can always find the answer and don't have to have either the web page or Google around to get to the answer.
[1] And as a "magic trick" you can hand a cashier what appears to them to be an odd amount of money, only to have them discover when they enter it into their register the change is a minimal number of coins/bills.
We used to memorise information, now we memorise meta-information - a mental map of concepts and trigger keywords. We have learned to quickly grok new concepts and we still have to understand how things work in order to do anything.
I definitely felt proud of myself for passing, especially when the other 6 senior linux admins all failed because they were too arrogant to study or prepare.
nautil.us/issue/40/learning/how-i-rewired-my-brain-to-become-fluent-in-math-rp
Or Feynman on the need for mathematical fluency to do physics:
> What we have to do is to learn to differentiate like we know how much is 3 and 5, or how much is 5 times 7, because that kind of work is involved so often that it’s good not to be confounded by it. When you write something down, you should be able to immediately differentiate it without even thinking about it, and without making any mistakes. You’ll find you need to do this operation all the time—not only in physics, but in all the sciences. Therefore differentiation is like the arithmetic you had to learn before you could learn algebra.
> Incidentally, the same goes for algebra: there’s a lot of algebra. We are assuming that you can do algebra in your sleep, upside down, without making a mistake. We know it isn’t true, so you should also practice algebra: write yourself a lot of expressions, practice them, and don’t make any errors.
Of course, in this particular discussion re: javascript, I think the design of the language doesn't help much here. Consider Javascript's `Date`, which the OP calls out as an API with a particularly difficult to remember set of conventions. Authors of languages and libraries can remedy this by having a coherence in design, naming, and behavior that help people build mental structures to memorize how these work and achieve the kind of fluency they need to do things without googling. Ruby's standard library I think is particularly good at this(here "principle of least surprise" helps not just with discovery, but retention).
EDIT: also want to add that using documentation and external resources is totally valid, as the grandparent comment states. There's just a balance to be had between relying on Google versus what you can draw from your mind quickly. Also think it's worthwhile to note that there is interesting work to be done in making documentation systems better and more integrated into our runtimes, see for example: https://www.geoffreylitt.com/margin-notes/
I've been exploring building a tool which is sort of a "universal search bar" for programming questions: finding answers via google, searching local repos, finding code snippets you've saved, etc. Another way to think of it is like an extension of your memory.
The idea is to make the information super fast to retrieve so you break don't break flow while you're programming.
For anyone who's curious, I'm collecting interest here: https://forms.gle/8q9nPUc22t6WDFsG7
I also looked into freelance jobs lately, and it's pretty crazy there too, especially with the JS' frantic mutations. You'd mostly need a handful frameworks and a whole load of specialized microsolutions, but still: last year everyone was using Ionic, now React Native is everywhere. Web APIs are also evolving nonstop. Chill out for some months, and you're lagging behind the others.
And that's not even beginning to mention compiling other people's C programs under MacOS. Pretty sure that ‘The voodoo of satisfying the compiler’ would be a book of respectable thickness without ever getting into programming proper.
I know gradle, and pretty well at that. I had to learn the basics of maven to develop a Jenkins plugin (at work). Developing jenkins plugins for a long time required using maven. Now there's the option for using gradle, but my recollection was that it was a sub-par experience.
https://google.com/search?q=site:docs.python.org/3+%s&btnI
(That last character is a capital "eye"/I, for "I'm".) It does a Google "I'm Feeling Lucky" search for your query, and restricts the results to the Python docs. So, e.g., I can type: py enum
And get the Python docs for the enum module.I recommend this for MDN, too, e.g. I can type,
mdn map type
and get the JS `Map` docs.I need to add one for crates.io & the Rust STL. Note, of course, that this sends your searches to Google by virtue of using the "I'm Feeling Lucky" functionality.
!py enum
!mdn border-radius
!crates webgl
!rust vectorIt's very barebones MVP at the moment, but you can expect more features very soon. Open to feedback!
Perhaps this is a reference to the interviewing process. Tests are a different thing, though. I’ve been on practical technical screens where you can google, because the test was about building a larger system, and they don’t care if you don’t remember this or that API syntax. But at the same time I get if you’re trying to assess someone’s aptitude for devising novel algorithms, sometimes a closed book test makes sense.
I think there are many devs (myself included earlier in my career) that push back in the algorithm tests because, well, it’s really hard. How often do you have to derive novel algos? A lot of our work is kind of UI frontends to DBs or gluing things and most of the sort of hard scalable algorithm problems someone else has implemented in a library. So why go through 6 months of really hard study, just to get that kind of job?
Well, I think here should be “maker” roles where you can bypass the hard CS stuff and just crank code, if you have an impressive portfolio of work. But having a deep understanding of data structures (not just arrays and maps) and algorithms really gives you a mastery of your craft, especially around performance and scalability.
Nobody should be screened out because they didn’t remember a particular bit of syntax though. (But it should be noted most algo tests don’t require anything but the language basics.)
I've met lots of younger devs who have varying degrees of impostor syndrome, so anecdotes like this probably help people like that feel less bad about not knowing everything.
And from what I've seen, those who don't google consistently also fail to understand the answers they find when they do google things. It is, in fact, an essential skill.
Really enjoy taking advantage of it and reassuring the younger kids (only two or three years younger than me) that they're more than capable of this shit. And it helps me be more confident when I'm at work - at school they see me as the guy with all the answers (ha, I wish - but it's a good reminder that we're all our own worst critics).
For example, if your solution involved generating all permutations of a sequence, and you didn't remember how to do that efficiently, I would let you make up a black box function that just does it. We might come back to this later in the interview, but I'm generally uninterested in whether you memorized an algorithm for it or remembered how to call the standard library function that does it.
That said, if you make up the black box function, I might dig into why you designed the function signature the way you did, and I'd do that to see whether you can talk about code design from a "other people will read and use and debug your code" perspective.
In any case, there's a lot of strategies to show that you understand a concept without relying on exact memorization. For example, a common answer I give if I can't remember something might be something like: "The language has a sort function that can accept a list, I don't remember the exact API or the underlying implementation but let's assume it's n log(n) as that's a common runtime complexity for sorting--I'm going to define that as 'sort(listArg)'." I don't remember the exact function, so I'll just define and explain how it might work myself. If you're expected to be able to compile the code you're writing, simply ask the interviewer and explain the API you're looking for, I've had great success with that as well and prefer when an interviewee asks me over staring at the screen or board.
If it's a problem where you're expected to produce some algorithm, if you can't come up with any solution, explain to your interviewer what you're stuck on. They may provide a hint that will get you rolling. I had this happen during an interview at Microsoft (spoiler, I got the job) where I forgot how to determine the length of the hypotenuse of a triangle haha. The interviewer wrote the formula on the board and we moved on. Interviewer later told me I seemed nervous and he chalked it up to a brain fart--good call, I was really nervous! The point of that problem wasn't to see if I knew the Pythagorean theorem--it was just a small piece of the puzzle I was stumped on. Similarly start from a simple, naive solution, and interatively optimize rather than trying to recall a perfectly optimal solution. If time is running low, explain your intended optimization or ones you think might be meaningful, making note of any uncertainties in that explanation.
I've worked at Microsoft, Amazon, some other notables and interviewed at many others. I am speaking from that experience. Others may have better ideas. Of course, not all places approach this in a reasonable fashion and some are just missing the point entirely with their interview and they do expect you to somehow memorize everything.
It's a whiteboard, I'm looking out for far more important things than whether the method is named `size` or `length`.
But I do think that Computer Science Jeopardy on a whiteboard is a bad idea.
A shitty interviewer will follow a rigid script and "ding" you on trivial errors.
I see it at least a couple times a week on sub-reddits related to software development. Junior devs who are convinced more senior developers are super-geniuses who know everything from memory.
A simple example. I'm working with Rails, Django, Phoenix and React (3 different projects). I know I need to do a strftime but I don't remember the exact details in any of Ruby, Python, Elixir and JavaScript. I always google them or grep the source code for other instances.
I try to dissuade this kind of thinking when I see it: I like answering people's questions, and I take pride in knowing a lot of stuff. But there's way more stuff that I don't know than that I know. And I might need these folks' help with something I'm unfamiliar with, so I don't want them thinking they're "below" me and there's no way they could know something I don't. I'm sure they do!
Consider this, many of the most novel algorithms were published without ever being run in actual software or in part of a larger system.
Most screens also include a systems design test. Maybe you could argue all we ever should do is system design tests. But they don’t always involve coding.
https://www.quora.com/How-will-you-explain-Inversion-of-Cont...
Yes the whole interview process is based on the idea of doing stuff for the company that you wouldn't actually do.
Indeed I interview my candidate's ability to find resources, to know what considerations are needed, how to deal with IDEs, collaborative tools, the git protocol. I will fire someone on the spot for implementing an academic algorithm if there was a library and potentially peer reviewed library they should have used instead.
The process for successful interviewing at places that use whiteboard testing for interviewing involves digging in and putting in a lot of hard work studying previously unknown concepts-- work that most people don't consider very fun.
To me, this sounds like exactly the kind of thing that a person will need to do to be successful in their first few months in a big company. Learning about their particular systems, authentication and authorization methods, security audit procedures, deployment methods, how they do dependency injection, logging, diagnostics, troubleshooting...
The problem is that people naturally blame themselves for not knowing everything rather than accepting that we have built monuments of trash code that nobody should be expected to understand and that therefore we should stop doing that and stop using that.
Ideally, I'd be able to have tasks that are highly specified in advance and with priorities that are stable enough that I do not have to have multiple social interruptions per day in order to be on the correct task.
Basically, I wish I could achieve productive software development from an isolated cabin without an internet connection to provide distractions, with lots of subtle natural ambiance and my own thoughts instead of interruptive social interactions, and synchronize my work product with society on the same cadence with which I would travel to town to get groceries.
Obviously, this is not the situation.
I would call these "user" roles. And perhaps there is a space for a "professional software user" career as we continue building software so unnecessarily complex that only a professional can use it.
Can you give an example?
I.e. you have a search field and want to show the possible matches as you type. With each new char you’re calling this search and getting back a list of words. The dictionary is in memory in whatever data structure you choose. You only have to return matches if the search is 3 or more chars long.
Now, how does your implementation scale when the dictionary has a million words?
I have done what you could call deriving novel algorithms, and in a commercial context no less[1]. What is or is not an algorithm not very well defined. There was a famous paper which defined an algorithm as "logic + control", which could really describe any code that we write.
I think what the experience taught me (where a CS education might help) was how to think algorithmically. The point of algorithmic thinking and algorithmic code is to be able to prove (formally or informally) that certain undesirable states are impossible. Algorithms focused around performance have proofs that unnecessary computations are not performed, cryptographic algorithms have proofs that secrets are not revealed during the computation, concurrency algorithms prove that data races do not occur, and so on.
It's actually quite easy to apply this sort of thinking to highly problem-specific code. The more specific the code is, the stronger the guarantees you can prove.
What becomes more difficult is writing code that is both generic and is able to make interesting guarantees about the state space of it's execution. It's the code that kind of code (generic with strong guarantees) that are what people typically mean by "algorithms".
[1] Not really as bad as this https://xkcd.com/664/
Screening and interview selection is driven by need. If one needs a subject matter expert in specific area, it does make a sense to test the person's familiarity with subject without googling.
It also helps to test Duning-Kruger effect. [1]
But this is wrong to assume that googling is bad. Being able to search, assimilate and effectively use information (by book or Google), is also a very important skill in itself.
I feel doing a test to figure out if the person has understood some common data structures and algorithms is good to see how a person approach and solves the problems, since programming is still an inherently logical puzzle solving.
This has been the opposite of my experience. Earlier in my career there was a lot more "sit and think about how to assemble these basic building blocks." Now it's a lot more "man, it would be nice if complex object A could play well with complex object B, I wonder how to make that work and what the pitfalls are." I'm googling different things than I used to, sure, but pretty much any task I'm tackling at this point involves a fair amount of googling for docs, github issues, stack overflow, etc.
A technician at CERN maintaining the accelerators is probably pretty damn smart, they probably also understand some particle physics. They may not be the ones driving/designing the experiments and they probably aren't getting their names on those physics papers but that doesn't mean they didn't contribute any value...
Which isn't the difference between doctor and nurse, more like an MD and PhD in medicine, one focused on practice, the other research.
Computer Scientists - Come up with the foundational algorithms etc.
Software Engineers - Translate and map those foundational algorithms into more readily available tooling, occasionally directly building a complex system using engineering principles.
Software Developers - Use the tooling created by software engineers to create user friendly solutions for the masses, aka developing apps or websites.
Of course, no manager reads The Mythical Man Month, and those that do don’t follow it.
https://reddit.com/r/emacs/comments/cs6cb4/instant_stackover...
https://devdocs.io/ is a free alternative. It’s a web app that can be set up to work offline. It was missing a few convenient features of Dash last time I checked, but I can’t remember which features those are right now.
"lxde" - this morning installing a window manager in userland app on my Galaxy S10+ while waiting for some batch processes to finish.
Dash currently costs $30. For anyone who doesn’t want to commit to that, you can also try https://devdocs.io/, a free web app alternative with fewer features. DevDocs can even work offline, like Dash does.
“cors - today is going to be bleak” as the first search of the day resonates with me on a deep level. Our field is incredibly complex, and some parts of it we just like to not think about too much.
"caniuse position sticky"
"ERR_SSL_PROTOCOL_ERROR angular ng serve"
"hash bitbucket reference jira"
And I've been at this for decades! I remember the bad old days of reference manuals. This is a walk in the park!
I say all this as somebody who grew up without the internet, let alone computers in homes so primarily developed the skills to self learn from the local information and more so, the ability to work it out myself. With the internet, you save reinventing the wheel as you can look up what wheel you need and where. But the ability to build a wheel is always a skill you should hone every once and a while. After all 5 9's SLA's is still moments when you won't have internets.
That all said, I'm pondering analysing my browser history more, be educational. Certainly worth doing just for your job reviews to justify what training you would benefit from the most.
1) What ‘level’ of engineer do you consider yourself to be, and does your employer consider you to be? (for example, do you have employees who are junior to you) 2) What’s your income from that job? 3) Do you think that income is fair and appropriate?
Apologies for the deep-dive in to details you may be uncomfortable sharing, they are important context that very few people share.
It's too much, and it changes all the time. We need a near-telepathic reference to get the necessary info when required. Thankfully, we have that and it makes the job possible.
“dl vs ul”
ol = countable items in a pertinent sequence
dl = key value pairs
table = a matrix of three or more keys and values
ul = Unordered List
ol = Ordered List
dl = Definition List
Definition List is the only description not immediately obvious, but understanding a definition as a key/value pair clears things up and isn't hard to remember.
That "Provisional headers are shown" Chrome message drives me crazy. Some time ago, I was able to disable some flags which made it go away temporarily, but now it's showing again, presumably after Chrome made some changes. It's a problem because it means that it's not showing the real request headers. Does anyone know how to fix this for good?
I'm baffled any time someone says chrome's dev tools are better. They lie, and usually about the single most important thing I'm looking for. That is not better.
A lot of my work involves using Windows API and it has been around for so long that whatever issue I am facing, someone probably has had it before, and there might be an obscure function that already does what I'm trying to implement or work around.
But I do not see this pessimistic. We developers work in large domains and it is good to have a companion on your side that enables you to build better applications: Google.
edit: and of course StackOverflow when I briefly worked as a perl dev there.
Amen.Been there done that.
It funny how much background knowledge is required to know what to google.
edit- Had to look up who actually said this
-me
> writing cookies
> string contains
> how to see request headers in chrome
I mean, obviously I'm trying to be snarky here, but I'm not sure how a professional "software engineer" focused on web development types such generic queries into the browser after working on it long enough to be "professional".
There should be no shame in googling things.