Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

RandomBlue posted:

Exactly, I'm amazed there are this many posters that either have no problem with the behavior I described or don't see the issue.

The design case for this function (and seriously, almost every language has this function, it's a very common use case) is along the lines of "normalize a possibly relative path provided by a trusted source". You are misusing the function to try to restrict the paths available to an untrusted source, which is almost the exact opposite of what the function is for. You should probably instead be filtering the input to ensure it doesn't have something like ".." and doing other sanitization on the input.

Adbot
ADBOT LOVES YOU

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

leper khan posted:

I'm more hung up on asking someone to do something you explicitly never want them to do. Implementing a simple state machine is about as complicated as fizz buzz and is something I've needed to do numerous times over the course of my career.

The correct way to sort something in most languages I use is to provide a comparison function (if the default isn't suiting) and call the sort method. Unless you're dealing with a large distributed data set, in which case you probably want to distribute the set across however many nodes, use whatever general sorting technique on them (call language's sort), and merge the results. If you are asking me to write a custom sorting algorithm, I'm going to need to waste 10-15 minutes figuring out why you would want me to do such a thing when the fact is that you probably don't care or want to go into cache locality at that point. Irrespective of the likelihood that the provided algorithm addresses those concerns better than whatever I'm going to vomit onto you in 3-5 minutes.

It really feels to me like you're misunderstanding the point of this sort of interview question.

I've asked people to sort a list in an interview before. I've also asked them to swap variables, or reverse a string, or implement FizzBuzz. There are lots of ways to accomplish these tasks. As an interviewer, I do not care even in the slightest how they go about it. If a candidate sorts a list by calling the standard library function, that's fine. If a candidate sorts a list by manually implementing a bubble sort, that's also fine. Hell, if a candidate wrote some client to a JobInterviewOMatic web service that automatically solves inane interview questions for them, that would also be completely fine.

The point is not to critique the candidate's choice of methods. If I ask someone to sort a list, then I don't really care how they go about it, and to be honest I don't even care if the list actually gets properly sorted. If they have an off-by-one error that causes them to not include the last element of the list or something then I'm not going to hold that against them. If they try to use std::sort but forget what it's called and write std::sort_list or something instead, that's still successful enough. The point is that more than half of the candidates that I have interviewed were completely, totally, 100% unable to write any code whatsoever. All that I want is for a candidate to demonstrate that they have some sort of solution in their head, and they are capable of somehow conveying that solution to a computer.

If a candidate can't even get a recognizable start on "sort a list" then I'll try to be generous and move on to a different simple test like "swap these two variables" or "reverse this string" or "count the number of words in a string" or whatever. Sometimes a candidate just blanks on a particular problem for some reason, or they panic, or something. It happens. But I want to reemphasize, for more than half of the interviews that I have conducted, we went the entire technical interview period going over CS 101 style problems and the candidate was completely unable to produce anything resembling a solution. I have no idea why these people want to interview for coding positions, because they appear literally unable to code.

Once I have a candidate that has apparently actually touched a programming language at some point in their life prior to the interview, I'll start asking them more real questions, and I'll probably use their solution to the inane filter question as a jumping-off point. But these aren't, like, trick questions where I'm going to fail someone because they did/did not use the "right" way to sort.

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

Gazpacho posted:

Those who defend git's intuitiveness but do not have Mercurial experience should be aware of a few things.

Honestly, I think two of the three things you listed make the mercurial UI worse than git's, based on my experience.

Gazpacho posted:

- Mercurial has ordinal revisions. Meaning, numbers starting from zero. They're local to each clone, and exist concurrently with the hash revision IDs. Mercurial could work without them, but they exist for UI benefit, so that users can specify ranges of revisions with ranges of numbers, and not "ancestors of this but not this" which borders on writing a script.

Having an obvious revision identifier which is not portable to different clones is a user-hostile mistake. It results in people trying to communicate "look at revision 17" and having their coworker look in the wrong place, because neither understood that they were not appropriately communicating a global identifier.

Gazpacho posted:

- Mercurial has rebasing, hard resetting, history rewriting, partial committing. All that stuff in git that's handy if you're prepared to learn it, but not strictly necessary. It comes in the distribution but it's TURNED OFF, because new users shouldn't be bothered with it. When you're ready for one of these features, you can enable it in your config file and go.

Having features which are unavailable until a config file is modified is a user-hostile mistake. It results in people writing scripts which mysteriously fail for other users, or it results in some users accidentally breaking their config because they want to use one of these tools, and it means that you have to defensively write documentation and tooling as if all of your users are using their own uniquely personalized VCS instead of a single well-defined program.

Gazpacho posted:

- Mercurial has no command "forms" based on the the post-option arguments, because expressing variations is what options are for. As a result, it can follow the longstanding Unix command line convention of using "--" to separate options from trailing arguments, not some trailing arguments from others.
- As an example if you want to rebase revisions from A to B onto C, Mercurial rebase requires you to tag each of those with an option, rather than specifying two of them (which two?) in a particular order (which?) and the third with an option that modifies (or maybe doesn't) the semantics of the other two.

This is fair. Named arguments are more self-documenting than positional arguments, just like in programming languages.

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

Gazpacho posted:

So it''s user-hostile, where the user is the developer of consumer of a script. You're kind of making my final point here. The goal should be to make something that serves its purpose without an ecosystem of scripts.

e: which is not to say that Mercurial lacks an ecosystem. It's just coded in Python, not bash, and at that level features are not turned off.

I mean, this is a completely fair point, but there are definitely communities of users who can and do write shell scripts to automate tasks, but are not software engineers and can't program a drat thing in Python. I'm probably colored in my perception because I work in a large team where git was specifically chosen as "less magic" than mercurial by a group of people who were essentially novice users of revision control - in many cases I would classify my users as non-programmers, and they value being able to write down a sequence of commands and have them reliably do the same thing for everyone more than they value the tool being easy to understand, because they just aggressively script every single flow they use.

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

LongSack posted:


Disagree. If you use clamp(1,value,value) the results will be different if clamp is defined as clamp(min,max,value) or clamp(max,min,value). This is quite obvious, so I am not sure what you are suggesting here.

In the spirit of the thread: Clearly clamp should just take three parameters in arbitrary order and always return the median. Then there can be no confusion.

Adbot
ADBOT LOVES YOU

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

ultrafilter posted:

I briefly looked into generating a lookup table using templates but that's way too much effort for me.

code:
#include <array>
#include <cstdint>
#include <iostream>
#include <utility>

template<size_t i>
struct IsEven {
    constexpr static bool isEven() {
        return !IsEven<i-1>::isEven();
    }
};

template<>
struct IsEven<0> {
    constexpr static bool isEven() {
        return true;
    }
};

static const size_t MAX = 65536;

template<size_t... Is>
constexpr auto precomputeIsEven(std::index_sequence<Is...>) {
    return std::array<bool, MAX>{ IsEven<Is>::isEven()... };
}

constexpr auto isEven = precomputeIsEven(std::make_index_sequence<MAX>());

int main(int argc, const char *argv[]) {
    for (unsigned int i = 0; i < MAX; ++i)
        std::cout << i << " is " << (isEven[i] ? "even" : "odd") << ".\n";
    return 0;
}
I have been paid actual money for writing code that does this trick for a "real" problem.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply