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.
 
  • Locked thread
piratepilates
Mar 28, 2004

So I will learn to live with it. Because I can live with it. I can live with it.



Do at home programming tests are the worst unless they're textbook ones like codility just as a basic screener. Anything more than that and it's a great way for them to waste your free time while rejecting you for some minor thing that they may never even get back to you on.

Shruges - what's your opinion on something like jooq instead of an orm?

Adbot
ADBOT LOVES YOU

Jerry Bindle
May 16, 2003
if an interview doesn't go well, it just means that you're a bad fit for that company. it doesn't necessarily mean that you aren't competent.

i overheard some rear end in a top hat at my company talking about how an interviewee didn't argue enough. apparently the guy thoughtfully considered alternate solutions rather than obstinately stuck to his own idea, and this was a bad quality to have in that group. (that group is toxic and i would hate to be in it)

piratepilates
Mar 28, 2004

So I will learn to live with it. Because I can live with it. I can live with it.



Come to think it s homework assignment for a job application wouldn't be that bad if it started small and had stages of code review for you to improve your solution to their discretion -- that never happens though, the whole thing is kinda dumb.

Kilroy
Oct 1, 2000
Oh I'm not worried about being made fun of - my confidence as a developer is already shattered utterly by this along with the rest of the past year. There is not much lower to go and I'm starting to consider a career switch after I move back to the States.

Anyway here's the code, original first (removing the boilerplate):

code:
@ThreadSafe
public class PoorGroup
{
    String groupId;
    HashSet<Member> members;
    boolean shouldStop;

    class Member
    {
        String memberId;
        int age;

        Member(String memberId, int age)
        {
            this.memberId = memberId;
            this.age = age;
        }

        public String getMemberId()
        {
            return memberId;
        }

        public int getAge()
        {
            return age;
        }

        public boolean equals(Object o)
        {
            // It should be regarded as the same object when having the same `memberId`
            Member member = (Member) o;
            return this.memberId == member.memberId;
        }
    }

    public PoorGroup(String groupId)
    {
        this.groupId = groupId;
        this.members = new HashSet<>();
    }

    public void addMember(Member member)
    {
        members.add(member);
    }

    public String getMembersAsStringWith10xAge()
    {
        String buf = "";
        for (Member member : members)
        {
            Integer age = member.getAge();
            // Don't ask the reason why `age` should be multiplied ;)
            age *= 10;
            buf += String.format("memberId=%s, age=%d¥n", member.getMemberId(), age);
        }
        return buf;
    }

    /**
     * Run a background task that writes a member list to specified files 10 times in background thread
     * so that it doesn't block the caller's thread.
     */
    public void startLoggingMemberList10Times(final String outputFilePrimary, final String outputFileSecondary)
    {
        new Thread(new Runnable() {
            @Override
            public void run()
            {
                int i = 0;
                while (!shouldStop)
                {
                    if (i++ >= 10)
                        break;

                    FileWriter writer0 = null;
                    FileWriter writer1 = null;
                    try {
                        writer0 = new FileWriter(new File(outputFilePrimary));
                        writer0.append(PoorGroup.this.getMembersAsStringWith10xAge());

                        writer1 = new FileWriter(new File(outputFileSecondary));
                        writer1.append(PoorGroup.this.getMembersAsStringWith10xAge());
                    }
                    catch (Exception e) {
                        throw new RuntimeException("Unexpected error occurred. Please check these file names. outputFilePrimary="
                                + outputFilePrimary + ", outputFileSecondary=" + outputFileSecondary);
                    }
                    finally {
                        try {
                            if (writer0 != null)
                                writer0.close();

                            if (writer1 != null)
                                writer1.close();
                        }
                        catch (Exception e) {
                            // Do nothing since there isn't anything we can do here, right?
                        }
                    }

                    try {
                        Thread.sleep(1000);
                    }
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    /**
     * Stop the background task started by <tt>startPrintingMemberList()</tt>
     * Of course, <tt>startLoggingMemberList</tt> can be called again after calling this method.
     */
    public void stopPrintingMemberList()
    {
        shouldStop = true;
    }
}
And after I introduced some bugs and changed the behavior of the code:

code:
public class PoorGroup {

  private final static Logger               LOGGER = Logger.getLogger(PoorGroup.class.getName());

  private final String                      groupId;

  private volatile ExecutorService          executor;

  /**
   * I took the liberty of changing this to a CopyOnWriteArraySet. It removes the need to perform synchronization in
   * addMember() and getMembersAsStringWith10xAge(), but the assumption is that the number of members is not overly
   * large and getMembersAsStringWith10xAge() is called much more often than addMember() (i.e. the list of members is
   * traversed much more than it is mutated).
   */
  private final CopyOnWriteArraySet<Member> members;
  // private final HashSet<Member> members;

  // private volatile boolean shouldStop;

  public static class Member {

    private final String memberId;

    private final int    age;

    Member(String memberId, int age) {
      this.memberId = memberId;
      this.age = age;
    }

    public String getMemberId() {
      return memberId;
    }

    public int getAge() {
      return age;
    }

    @Override
    public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result + ((memberId == null) ? 0 : memberId.hashCode());
      return result;
    }

    @Override
    public boolean equals(Object obj) {
      // It should be regarded as the same object when having the same `memberId`
      if (this == obj) return true;
      if (obj == null) return false;
      if (getClass() != obj.getClass()) return false;
      Member other = (Member) obj;
      if (memberId == null) {
        if (other.memberId != null) return false;
      }
      else if (!memberId.equals(other.memberId)) return false;
      return true;
    }

  }

  public PoorGroup(String groupId) {
    this.groupId = groupId;
    this.members = new CopyOnWriteArraySet<Member>();
    // this.members = new HashSet<Member>();
    // this.shouldStop = false;

    this.executor = Executors.newCachedThreadPool();
  }

  public void addMember(Member member) {
    members.add(member);
  }

  /**
   * Tells the executor to finish currently queued tasks and quit. Should be called when finished with this PoorGroup.
   */
  public void close() {
    executor.shutdown();
  }

  public String getMembersAsStringWith10xAge() {
    StringBuilder buf = new StringBuilder();
    for (Member member : members) {
      // Don't ask the reason why `age` should be multiplied ;)
      if (member != null) {
        buf.append(String.format("memberId=%s, age=%d\n", member.getMemberId(), member.getAge() * 10));
      }
    }
    return buf.toString();
  }

  /**
   * Run a background task that writes a member list to specified files 10 times in background thread so that it doesn't
   * block the caller's thread.
   */
  public void startLoggingMemberList10Times(final String outputFilePrimary, final String outputFileSecondary) {
    // shouldStop = false;
    executor.submit(new Runnable() {

      @Override
      public void run() {
        int i = 0;
        boolean shouldStop = false;
        while (!shouldStop) {
          if (i++ >= 10) break;

          try (FileWriter writer0 = new FileWriter(new File(outputFilePrimary));
              FileWriter writer1 = new FileWriter(new File(outputFileSecondary))) {
            writer0.append(PoorGroup.this.getMembersAsStringWith10xAge());
            writer1.append(PoorGroup.this.getMembersAsStringWith10xAge());
          }
          catch (IOException ioe) {
            throw new RuntimeException("Unexpected error occurred. Please check these file names. outputFilePrimary="
                + outputFilePrimary + ", outputFileSecondary=" + outputFileSecondary, ioe);
          }

          try {
            Thread.sleep(1000);
          }
          catch (InterruptedException ie) {
            LOGGER.log(Level.INFO,
                String.format("%s interrupted while in Thread#sleep()", Thread.currentThread().getName()), ie);
            shouldStop = true;
            Thread.currentThread().interrupt();
          }
        }
      }
    });
  }

  /**
   * Stop the background task started by <tt>startPrintingMemberList()</tt> Of course, <tt>startLoggingMemberList</tt>
   * can be called again after calling this method.
   */
  public void stopPrintingMemberList() {
    // shouldStop = true;
    ExecutorService e0 = this.executor;
    this.executor = Executors.newCachedThreadPool();
    e0.shutdownNow();
  }
}
Is it because I removed the @ThreadSafe annotation? I hate computers.

Jerry Bindle
May 16, 2003
IMO the best answer is "oh, threading code, i'm not the right person to maintain this code. concurrency is a specialization that i don't have. concurrency should be handled by specialists".

the first step to doing a bad job is to do a job that isn't yours.

Symbolic Butt
Mar 22, 2009

(_!_)
Buglord
code:
                        catch (Exception e) {
                            // Do nothing since there isn't anything we can do here, right?
                        }
:crossarms:

Barnyard Protein posted:

IMO the best answer is "oh, threading code, i'm not the right person to maintain this code. concurrency is a specialization that i don't have. concurrency should be handled by specialists".

the first step to doing a bad job is to do a job that isn't yours.

what about faking it 'til you make it? :v:

Jerry Bindle
May 16, 2003
honestly though there is so much code stink in what they gave you, i don't know what they expected you to do. its either a stress-test to which there is no "right" answer, only degrees of failure, or an example of their code that you might have to work on. either way consider it a bullet dodged

Kilroy
Oct 1, 2000

Barnyard Protein posted:

honestly though there is so much code stink in what they gave you, i don't know what they expected you to do. its either a stress-test to which there is no "right" answer, only degrees of failure, or an example of their code that you might have to work on. either way consider it a bullet dodged
I've been dodging so many bullets lately.

CPColin
Sep 9, 2003

Big ol' smile.
Maybe they didn't like that you changed the indentation style? Or they felt package-private scope was good enough and felt insulted that you changed stuff to be private (like it should be). Or they really like the syntactic sugar of string concatenation and didn't like your fancy-pants use of a StringBuilder. Maybe they felt their use of a simple Runnnable was plenty and it didn't need the ExecutorService stuff. Or the logging stuff.

I can see how some of that, if they didn't already know about it, could look out of the blue an unnecessary. Maybe they should be part of this thread!

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
i'd say the most likely reason is that the startup programmer is an arrogant idiot (but i repeat myself...)

for example, if I had severe dunning-kruger syndrome and wasn't aware of try-with-resources, I might think that you'd introduced a bug with not cleaning up the file writers. I also might get offended when you fixed parts of my lovely code that weren't intentionally lovely for the sake of the assignment. your rewrite is overall much improved and the criticism you actually received doesn't make much sense.

--

as for my personal criticism of your code, that wacky indentation you used for fields is really bad (it looks kind of cool, but literally nobody wants to spend time maintaining that spacing...), and you should use a FutureTask or something else explicitly cancelable instead of wrangling interrupts yourself.

Jerry Bindle
May 16, 2003

Symbolic Butt posted:

what about faking it 'til you make it? :v:

a good strategy iff you can make it before faking it causes a problem

Kilroy
Oct 1, 2000

Jabor posted:

as for my personal criticism of your code, that wacky indentation you used for fields is really bad (it looks kind of cool, but literally nobody wants to spend time maintaining that spacing...), and you should use a FutureTask or something else explicitly cancelable instead of wrangling interrupts yourself.
It's a thing I have in my formatter so no maintenance but yeah, point taken. The other bit is exactly the sort of thing I came here for, so thanks :)

brap
Aug 23, 2004

Grimey Drawer
you're doing fine, gently caress those guys.

jony neuemonic
Nov 13, 2009

fleshweasel posted:

you're doing fine, gently caress those guys.

yeah, they handed you a pile of garbage and you cleaned it up a bunch. you're better off anyway, that's probably representative of what you would have been working with had they hired you.

triple sulk
Sep 17, 2014



https://www.jetbrains.com/toolbox/

jony neuemonic
Nov 13, 2009

:rip: upgrade discounts i guess. still, pretty cool for polyglots who can now use any of the tools for one price.

DONT THREAD ON ME
Oct 1, 2002

by Nyc_Tattoo
Floss Finder

fleshweasel posted:

you're doing fine, gently caress those guys.

NihilCredo
Jun 6, 2011

iram omni possibili modo preme:
plus una illa te diffamabit, quam multæ virtutes commendabunt

java layman here, any reason why

code:
    @Override
    public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result + ((memberId == null) ? 0 : memberId.hashCode());
      return result;
    }
isn't just

code:
public int hashCode() {
      return 31 + ((memberId == null) ? 0 : memberId.hashCode());
    }
(yes i know it's bikeshedding.txt)

CPColin
Sep 9, 2003

Big ol' smile.
Those two methods are equivalent and they're both wrong. They should have put parentheses around the (result + whatever) part. Otherwise, the multiplication gets evaluated first and is always (31 * 1).

sarehu
Apr 20, 2007

(call/cc call/cc)

quote:

code:
age=%d¥n"

:japan:

suffix
Jul 27, 2013

Wheeee!

Kilroy posted:

Oh I'm not worried about being made fun of - my confidence as a developer is already shattered utterly by this along with the rest of the past year. There is not much lower to go and I'm starting to consider a career switch after I move back to the States.

Anyway here's the code, original first (removing the boilerplate):

code:
And after I introduced some bugs and changed the behavior of the code:

code:
Is it because I removed the @ThreadSafe annotation? I hate computers.

i'm not sure that i would have used the CopyOnWriteArraySet, even just 10,000 - 100,000 members will probably start getting really slow
but documenting your assumptions are good and i wouldn't have held it against you
more like an interview question, "what happens if we have a million members?"

you could probably just use memberId.hashCode() directly, multiplying it by a prime doesn't do much unless you're storing it in a hash set together with strings
(i'm not sure if CopyOnWriteArraySet even uses hashCode(), but eh.)

imo it would have been an improvement to make sure writer0 and writer1 logged the same string

null checks should be in addMember and the Member constructor (throw an error), not in getMembersAsStringWith10xAge and hashCode.

that's just some small nits i see, i don't think they played any part in your rejection

Share Bear
Apr 27, 2004

since jetbrains is going subscription only, is there any way to make eclipse not look like a giant pile of poo poo?

Shaggar
Apr 26, 2006
the best you can do is set the theme back to classic but thats it. theming is really the only thing I don't like about eclipse.

Janitor Prime
Jan 22, 2004

PC LOAD LETTER

What da fuck does that mean

Fun Shoe

Share Bear posted:

since jetbrains is going subscription only, is there any way to make eclipse not look like a giant pile of poo poo?

are they killing the community edition as well? that one suits my needs just fine

coffeetable
Feb 5, 2006

TELL ME AGAIN HOW GREAT BRITAIN WOULD BE IF IT WAS RULED BY THE MERCILESS JACKBOOT OF PRINCE CHARLES

YES I DO TALK TO PLANTS ACTUALLY
gotta learn matlab. anyone know of a matlab book written for people who already know what a for loop is?

leftist heap
Feb 28, 2013

Fun Shoe

Share Bear posted:

since jetbrains is going subscription only, is there any way to make eclipse not look like a giant pile of poo poo?

No. It is perma ugly. They put a dark theme in a while ago and it is a total joke.

triple sulk
Sep 17, 2014



lol @ all the people getting mad about it going subscription

Pollyzoid
Nov 2, 2010

GRUUAGH you say?

Janitor Prime posted:

are they killing the community edition as well? that one suits my needs just fine

no

Valeyard
Mar 30, 2012


Grimey Drawer
My first three days have been pretty lovely. The team got given 2 grads because it was super understaffed with people leaving - and I can definetly see why people don't stick around

Jerry Bindle
May 16, 2003

coffeetable posted:

gotta learn matlab. anyone know of a matlab book written for people who already know what a for loop is?

how to use matlab:
1) bookmark this http://www.mathworks.com/help/matlab/
2) remember that 'mat-' stands for 'matrix'
3) assume any function you're looking for already exists, don't stop looking for it till you find it or proof that it doesn't exist
4) throw matlab away

Symbolic Butt
Mar 22, 2009

(_!_)
Buglord
get used to people mixing a lot of column matrices with row matrices and transposing all the time

woo

gonadic io
Feb 16, 2011

>>=
Got my first pull request declined today! Turns out that using existential types when there will literally never be more than two options is ""overkill"" and "phd code"

:rolleyes:

Mostly I just wanted to see if using them was possible.

Valeyard
Mar 30, 2012


Grimey Drawer

gonadic io posted:

"phd code"

Well, they're not wrong I guess

Valeyard
Mar 30, 2012


Grimey Drawer
Look at this guy with his smart code...who does he think he is

piratepilates
Mar 28, 2004

So I will learn to live with it. Because I can live with it. I can live with it.



Valeyard posted:

My first three days have been pretty lovely. The team got given 2 grads because it was super understaffed with people leaving - and I can definetly see why people don't stick around

good luck with your.......... two years there :confused:

Asshole Masonanie
Oct 27, 2009

by vyelkin

Share Bear posted:

since jetbrains is going subscription only, is there any way to make eclipse not look like a giant pile of poo poo?

a UI designed by engineers is destined to be fail

Captain Foo
May 11, 2004

we vibin'
we slidin'
we breathin'
we dyin'

Power Ambient posted:

a UI designed by engineers is destined to be fail

idk man bridges seem pretty easy to use

Notorious b.s.d.
Jan 25, 2003

by Reene

Share Bear posted:

since jetbrains is going subscription only, is there any way to make eclipse not look like a giant pile of poo poo?

subscription-only is the only sane way to pay for dev tools. it's not like the underlying tools your IDE integrates with are going to stop changing over time

piratepilates
Mar 28, 2004

So I will learn to live with it. Because I can live with it. I can live with it.



As long as they offer a cheap or free pristinely use/educational version then who cares, just expense that poo poo

They're still keeping the free ultimate education version though right??

Adbot
ADBOT LOVES YOU

gonadic io
Feb 16, 2011

>>=

Valeyard posted:

Look at this guy with his smart code...who does he think he is

overcomplicated is absolutely not the same thing as good, I don't know how well my sarcasm came across but i agree with them in hindsight

  • Locked thread