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
Doc Neutral
Jan 31, 2014

ulmont posted:

Conceptually, both a DFS and a BFS will search every cell until they find their target; the only difference is the order.

In a DFS, conceptually, the recursive algorithm looks like:

1. Have I found the target (maze[x][y] == 3 in your example)? If so, done.
2. If not, is there a child cell (that is, in your example, either a 0 or a 3 (traverseable terrain) in any untried direction)? If so, return the value of solve (that child cell). This part - exploring as far down (well, up, in your algorithm) a particular path as possible before backing up - is the key to a DFS.
3. If there is no child cell in any untried direction, back up until you find a new child cell of a higher node to try.

For DFS, this means you visit nodes in the order labeled here.



In a BFS, conceptually, the recursive algorithm looks like:

1. Have I found the target (maze[x][y] == 3 in your example)? If so, done.
2. If not, is there a child cell in any untried direction that has the target (look up, look right, look down, look left, whichever direction you didn't come from)? This part - exploring every child node at the same level before going deeper - is the key to a BFS.
3. If none of the child cells in any untried direction have the solution, pick the first child cell and then go further down.

For BFS, this means you visit nodes in the order labeled here.



Your algorithm looks up then tries to solve up, so it's DFS. (up all the way, then down all the way, then right all the way, then left all the way, etc.).

It doesn't look like it tracks all visited cells, though (if it gives up on the look up path, unwinding the stack will revert all visited cells up to 0), so I think it's going to end up checking the same cell a lot more times than it needs to.

Makes much more sense now, thank you so much for the clarification!

Adbot
ADBOT LOVES YOU

1337JiveTurkey
Feb 17, 2005

Sorry if this is a bit late.

The way I look at DFS versus BFS is the type of data structure that you use to store intermediate nodes to be processed. DFS tends to get written as an explicitly recursive algorithm but you can remove the call stack and replace it with an explicit stack in code iterated over with a loop. BFS doesn't have a nice recursive way to write it out (probably something involving coroutines though) but can be written as an iterative loop with a queue. At this point it's worth mentioning a fun little data structure called the deque that can be a stack or a queue at the same time. A search written with a deque therefore can do either BFS or DFS with remarkably little modification.

code:
Deque<Node> nodes = new ArrayDeque<>();
nodes.addLast(root);
while (!nodes.isEmpty()) {
	Node node = depthFirst? nodes.removeLast() : nodes.removeFirst();
	if (found(node)) {
		return node;
	} else {
		for (Node child : node.getChildren()) {
			// Superstitious programmer hates adding to beginning of array-based data structures
			nodes.addLast(child);
		}
	}
}
return null;
These aren't the only options by any means. If you think about it the fastest way to search is to use some sort of system where you look at the best candidates by some measure first (doesn't need to be perfect) and then try the other nodes. If you're able to define some sort of ordering on your candidates, either directly on them with the Comparable interface or indirectly with the Comparator interface, then you can use a PriorityQueue to sort the nodes. The method names are slightly different but the same structure is there.

code:
PriorityQueue<Node> nodes = new PriorityQueue<>(someComparator);
nodes.add(root);
while (!nodes.isEmpty()) {
	Node node = nodes.poll();
	if (found(node)) {
		return node;
	} else {
		for (Node child : node.getChildren()) {
			nodes.add(child);
		}
	}
}
return null;
I think there's a short hop from this to Dijkstra and A* searches from here but I'm feeling too lazy to think about that at the moment.

hooah
Feb 6, 2006
WTF?

1337JiveTurkey posted:

Dijkstra and A*

These are terms I haven't heard in many a year...

Hippie Hedgehog
Feb 19, 2007

Ever cuddled a hedgehog?
https://xkcd.com/2407/ is topical.

Andohz
Aug 15, 2004

World's Strongest Smelly Hobo
Is there any good "best practices" for java? I recently started a job as a java programmer and I'm trying to find some... source of sanity basically. I know basic stuff like SOLID/DRY/"code is read 10x more often that written", and in general I try to copy the style of whatever I'm working on but, well, when a 1k line for-statement makes it through code review I'm assuming I shouldn't use the code base as inspiration for clean code.

I'm new to java code and just want some way to sanity check my ideas, if possible. Code still goes through code review but I'd like to have some place to make sure I'm not reinventing the wheel or doing something stupidly elaborate before creating my pull request.

I found some oracle thing (that hadn't been updated in 20 years) but I can't manage to find it now so welp :|

hooah
Feb 6, 2006
WTF?
I think "Clean Code" is the most-recommended book, at least in my experience. Although I haven't gotten around to buying it, myself...

1337JiveTurkey
Feb 17, 2005

I think that Effective Java by Joshua Bloch is probably one of the best books in terms of understanding specific Java issues. The same author also wrote Java Puzzlers which cover subtle gotchas. Otherwise for general "Is this good Java?" advice, idiomatic Java doesn't really value terseness and if that thousand line for statement is mostly Spring bullshit, hopefully some day it'll just blend into the background.

Objective Action
Jun 10, 2007



Others have already covered my recommendations (Clean Code and Effective Java).

Once you have those under your belt one other thing I highly recommend is get a free copy of SonarQube, turn all the rules on, and scan every piece of code you write. There are plugins for every major IDE and standalone apps if you can't use an IDE for some reason.

~70% of the results will be opinionated bullshit but you will catch poo poo you never thought of and looking at the opinions and being forced to think about why you don't agree with that and are turning off the rule is very valuable imo. It won't teach you concepts to get good clean code the way the books will and it won't catch more elaborate logical errors but it absolutely will help you practice and can be useful to find spots where you have a knowledge gap.

Its some of the best code analysis tools around packaged into a super convenient frontend and you should absolutely take advantage of it.

Love Stole the Day
Nov 4, 2012
Please give me free quality professional advice so I can be a baby about it and insult you
As someone transitioning into the Java world right now, these things were super insightful and helpful for me:

Doc Neutral
Jan 31, 2014

1337JiveTurkey posted:

Sorry if this is a bit late.

The way I look at DFS versus BFS is the type of data structure that you use to store intermediate nodes to be processed. DFS tends to get written as an explicitly recursive algorithm but you can remove the call stack and replace it with an explicit stack in code iterated over with a loop. BFS doesn't have a nice recursive way to write it out (probably something involving coroutines though) but can be written as an iterative loop with a queue. At this point it's worth mentioning a fun little data structure called the deque that can be a stack or a queue at the same time. A search written with a deque therefore can do either BFS or DFS with remarkably little modification.

No not at all, it really helped a lot!



:v:

EDIT: Solved the problem with my BFS where I couldn't only show the shortest path, solved it by backtracking the visitation list from the end to start. Thanks for the help everyone!

Doc Neutral fucked around with this message at 17:07 on Jan 7, 2021

F_Shit_Fitzgerald
Feb 2, 2017



I'm trying to relearn Java after not touching it for years, and that's taking the form of jumping into the deep end of the pool and just writing code. My current project is writing a program to simulate a deck of cards, but I'm feeling dumb because I can't seem to figure out how to use the enum I declared for my Card class.

In my Card class I declared my enum as

code:
public enum Suit {HEART, DIAMOND, CLUB, SPADE};
with the intention to declare a Card object as something like this

code:
Card c = new Card(HEART, "2");
But HEART "cannot be resolved to a variable" when I compile. I know I'm probably making a boneheaded mistake, but I'm wondering if someone can fix my stupid (thanks in advance).

Twerk from Home
Jan 17, 2009

This avatar brought to you by the 'save our dead gay forums' foundation.

F_Shit_Fitzgerald posted:

I'm trying to relearn Java after not touching it for years, and that's taking the form of jumping into the deep end of the pool and just writing code. My current project is writing a program to simulate a deck of cards, but I'm feeling dumb because I can't seem to figure out how to use the enum I declared for my Card class.

In my Card class I declared my enum as

code:
public enum Suit {HEART, DIAMOND, CLUB, SPADE};
with the intention to declare a Card object as something like this

code:
Card c = new Card(HEART, "2");
But HEART "cannot be resolved to a variable" when I compile. I know I'm probably making a boneheaded mistake, but I'm wondering if someone can fix my stupid (thanks in advance).

Are you importing Card.Suit.HEART or just Card? If your Suit enum is a member of the Card class, you'll either need to reference it as Card.Suit.HEART, or import the member you want to reference directly.

F_Shit_Fitzgerald
Feb 2, 2017



Twerk from Home posted:

Are you importing Card.Suit.HEART or just Card? If your Suit enum is a member of the Card class, you'll either need to reference it as Card.Suit.HEART, or import the member you want to reference directly.

Ohhh...just Card. I forgot that in Java you had to do Card.Suit.HEART.


e: Yep; that fixed it. Thank you! This is exactly why I'm trying to knock the dust off my my Java skills.

1337JiveTurkey
Feb 17, 2005

Also you can use import static Card.Suit.* to just import the card suits directly like you want.

Sagacity
May 2, 2003
Hopefully my epitaph will be funnier than my custom title.
And use IntelliJ so it'll give you suggestions on what to import.

F_Shit_Fitzgerald
Feb 2, 2017



Sagacity posted:

And use IntelliJ so it'll give you suggestions on what to import.

Is it better than Eclipse? I've been using that because it was the Java IDE my university recommended. I've heard good things about IntelliJ, though.


1337JiveTurkey posted:

Also you can use import static Card.Suit.* to just import the card suits directly like you want.

Anything that saves typing out Card.Suit.HEART is great for me. Thanks!

1337JiveTurkey
Feb 17, 2005

F_Shit_Fitzgerald posted:

Is it better than Eclipse? I've been using that because it was the Java IDE my university recommended. I've heard good things about IntelliJ, though.

You can't control a Mars rover with it like Eclipse has been used for but professional developers tend to like IDEA more for its smart autocomplete, whole-project indexing and other features.

Hippie Hedgehog
Feb 19, 2007

Ever cuddled a hedgehog?

F_Shit_Fitzgerald posted:

Is it better than Eclipse? I've been using that because it was the Java IDE my university recommended. I've heard good things about IntelliJ, though.

Yes. Infinitely yes.

(Protip: Don't assume Java advice from your time at uni is still valid. The language and tool chain have both improved immensely from even 5 years ago. Me, I learned in Emacs but once I was working, we use first Netbeans, then Eclipse, then finally IntelliJ came along and I didn't have to wait for the freaking IDE to catch up with my typing any longer.)

Janitor Prime
Jan 22, 2004

PC LOAD LETTER

What da fuck does that mean

Fun Shoe

Hippie Hedgehog posted:

Yes. Infinitely yes.

(Protip: Don't assume Java advice from your time at uni is still valid. The language and tool chain have both improved immensely from even 5 years ago. Me, I learned in Emacs but once I was working, we use first Netbeans, then Eclipse, then finally IntelliJ came along and I didn't have to wait for the freaking IDE to catch up with my typing any longer.)

Look at this guys granytyping, not double VPN jumping like he should.

seriously pray you don't have to do any coding in a java ide over remote desktop, it's the worst

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
I do most of my coding over remote desktop and it's fine, lol

(but the machine I'm remoting into is literally in the same city so latency is minimal)

Love Stole the Day
Nov 4, 2012
Please give me free quality professional advice so I can be a baby about it and insult you
Java questions thread: Stream.of("poop")

Eezee
Apr 3, 2011

My double chin turned out to be a huge cyst

Jabor posted:

I do most of my coding over remote desktop and it's fine, lol

(but the machine I'm remoting into is literally in the same city so latency is minimal)

My flatmate has his remote desktop on Azure and it works surprisingly well. The low refresh rate obviously sucks, but there is very little perceivable latency when typing.

smackfu
Jun 7, 2004

I ran into some real library code that had an interface that looked like this:

quote:

<T> T entryAt(int index);
Then in the implementation cast the value to T before returning it.

So you could do:
int i = entryAt(0);
Or
String s = entryAt(0);

No cast required, no compile time type checking, it just failed at runtime with a class cast exception if you picked wrong.

Is this as terrible as I think it is?

ivantod
Mar 27, 2010

Mahalo, fuckers.

smackfu posted:

I ran into some real library code that had an interface that looked like this:

Then in the implementation cast the value to T before returning it.

So you could do:
int i = entryAt(0);
Or
String s = entryAt(0);

No cast required, no compile time type checking, it just failed at runtime with a class cast exception if you picked wrong.

Is this as terrible as I think it is?

So what is this, some kind of collection that can contain elements of different types and it's up to the caller to know what is the type at a particular index (since the generic type T is only on the method and not on the whole class as far as your example shows)?

If so, then it's not great, no.

Volguus
Mar 3, 2009
If it would return Object at least you could ask it what kind of object it is before casting. Though I see it's returning an int so I'm totally confused what it holds in there. This looks wrong anyway you slice it.

asur
Dec 28, 2012

Volguus posted:

If it would return Object at least you could ask it what kind of object it is before casting. Though I see it's returning an int so I'm totally confused what it holds in there. This looks wrong anyway you slice it.

The int example either shouldn't work or the compiler is unboxing Integer to int automatically.

This interface makes next to no sense without context as the standard case <T> is on the class and this example have a compile error unless the object type matched the type of the variable your assigning it to. In general without a very specific use case this is terrible design as it lets you cast to whatever you think is correct without compile time checks and will generate runtime errors unless your code is perfect.

CPColin
Sep 9, 2003

Big ol' smile.
It looks a lot like Generics By Someone Who Doesn't Understand The Point Of GenericsTM

necrotic
Aug 2, 2005
I owe my brother big time for this!

smackfu posted:

I ran into some real library code that had an interface that looked like this:

Then in the implementation cast the value to T before returning it.

So you could do:
int i = entryAt(0);
Or
String s = entryAt(0);

No cast required, no compile time type checking, it just failed at runtime with a class cast exception if you picked wrong.

Is this as terrible as I think it is?

I use this for a bit of testing code, where some encoded data is received and is normally sent to a backend. In tests I can know what type it should be when decoded so it works great.

I'd never* use it in production code.

smackfu
Jun 7, 2004

Here’s the link:

https://github.com/eclipse-vertx/ve...eImpl.java#L146

Private Speech
Mar 30, 2011

I HAVE EVEN MORE WORTHLESS BEANIE BABIES IN MY COLLECTION THAN I HAVE WORTHLESS POSTS IN THE BEANIE BABY THREAD YET I STILL HAVE THE TEMERITY TO CRITICIZE OTHERS' COLLECTIONS

IF YOU SEE ME TALKING ABOUT BEANIE BABIES, PLEASE TELL ME TO

EAT. SHIT.


1337JiveTurkey posted:

You can't control a Mars rover with it like Eclipse has been used for but professional developers tend to like IDEA more for its smart autocomplete, whole-project indexing and other features.

This is a good answer, eclipse is more flexible especially for things like embedded work or having multiple languages and codebases open at once, but jetbrains is much snappier and has overall better coding experience. Also Eclipse tends to be a giant memory hog on large projects and can occasionally crash.

e: I use both and each have some things they're better at, but I concede that jetbrains IDEs are definitely more polished and stable. Visual Studio (the full one) is somewhere between the two.

Private Speech fucked around with this message at 00:34 on Mar 5, 2021

CPColin
Sep 9, 2003

Big ol' smile.

I like that future() function that it calls, which does a bounds check, then performs an array operation that does the same bounds check, except correctly (it should be >=, not >).

Soricidus
Oct 21, 2010
freedom-hating statist shill

smackfu posted:

I ran into some real library code that had an interface that looked like this:

Then in the implementation cast the value to T before returning it.

So you could do:
int i = entryAt(0);
Or
String s = entryAt(0);

No cast required, no compile time type checking, it just failed at runtime with a class cast exception if you picked wrong.

Is this as terrible as I think it is?

This trick can be useful in very limited cases as a last resort way of reducing excessive casting boilerplate, but I would never write a method that used it that did not have “unsafe” in its name.

Definitely a code smell.

i vomit kittens
Apr 25, 2019


I'm having a weird problem with a simple survey/polling function in my Spring app. This is the fourth time that the app's been used by real people, and the problem's never occurred before (including in tests) with no changes to the code since it's started. Somehow, duplicate records are sometimes being saved to the database. I thought I was already checking for this; each Poll object has a 'usersVotedIn' array that keeps track of who's answered it, and there's an if statement that will cause the function to return if the requester is already in it. I've also checked the request logs for my server and it's not being caused by a person sending multiple requests with the same parameters.

code:
fun submitPoll(
        organization: Organization,
        poll: Poll,
        choice: PollChoice,
        requester: User
): ResponseEntity<String> {

    if(requester.checkPermissions(organization, "UNAPPROVED")) {
        return ResponseEntity(HttpStatus.UNAUTHORIZED)
    }

    if(choice.poll != poll || poll.endTime < Date() || poll.usersVotedIn.contains(requester)) {
        return ResponseEntity(HttpStatus.BAD_REQUEST)
    }

    val voteKey = UUID.randomUUID().toString()
    choice.keys.add(voteKey)
    pollChoiceRepository.save(choice)
    poll.usersVotedIn.add(requester)
    pollRepository.save(poll)

    return ResponseEntity(voteKey, HttpStatus.OK)
}
(note: the purpose of the voteKey is to allow users to verify that their response was recorded correctly while preventing me from easily being able to see who voted for what. The result of a poll is also calculated by comparing the lengths of each choice's 'keys' array)

There are a few things going on here that are making my head spin:
1) Both the poll's 'usersVotedIn' and the choice's 'keys' array are having duplicate rows added.
2) The same UUID is being added to a choice's 'keys' array multiple times. This makes me think that the problem is not the entire function being called multiple times, or else it would be generating a new UUID.
3) The problem does not happen for every poll, but when it does happen it affects almost everyone who voted. I have yet to see the problem occur on just a few people for any particular poll.
4) The problem happens an inconsistent amount of times per person. One user might have their vote duplicated once, while another might have 4 duplicate records.
5) I tried to add in a few extra print statements to track what exactly was going on. In order to do this I killed the system service that normally runs the process and started it manually. The entire time I was watching the server's output, the problem NEVER occurred despite it happening in 3 of the 4 polls that took place before I started observing.

e: The classes for Poll/PollChoice:

code:
class Poll(
        var question: String,
        @JsonIgnore @ManyToMany var usersVotedIn: MutableList<User> = mutableListOf(),
        var startTime: Date,
        var endTime: Date
) : BaseEntity<Long>()
code:
class PollChoice(
        @ManyToOne var poll: Poll,
        var text: String,
        @JsonIgnore @ElementCollection var keys: MutableList<String> = mutableListOf()
) : BaseEntity<Long>()

i vomit kittens fucked around with this message at 02:15 on Mar 23, 2021

Volguus
Mar 3, 2009
To me this sounds like a relationship problem with PollChoice and/or Poll. Can the voteKey be made unique in the database wherever it's being saved? And/or the foreign key to it? At least that way duplicate records cannot be entered and you can add a try/catch and log the stacktrace to see maybe who's the culprit.

Without knowing more about the data model in here it's quite hard to make heads or tails about it.

i vomit kittens
Apr 25, 2019


drat, I knew I was missing something. I just added in the class definitions for Poll and PollChoice.

Putting a unique constraint on the keys was my first thought, and probably something I should have done in the first place. I guess I'd have to be pretty careful about how I handle the error it would generate though because I don't want:

a) Duplicate records to still be added to the usersVotedIn array anyways (while this shouldn't actually affect anything in practice it will still annoy the gently caress out of me to know that it's happening).

b) If it tries to add a duplicate and the request "fails" (despite their vote actually being recorded) the user will think that their vote did not count and the front-end would also not allow them to attempt to vote again.

Volguus
Mar 3, 2009
Oh wait, that method receives the objects from the browser itself (well, after it goes through the HttpRequest and friends), right? Those objects are not, yet, managed by the EntityManager. When you call save() on the object it may think that's a new thing and makes a new object with all the relations and all. That's just my assumption though. I would just retrieve managed objects within my transaction from the repository. That is, unless they're already managed and everything is within a transaction and everything is cool and all, at which point I don't know.

i vomit kittens
Apr 25, 2019


The browser just sends the IDs of those objects, I have another function that gets them from the database and passes them into this one.

Pedestrian Xing
Jul 19, 2007

i vomit kittens posted:

Putting a unique constraint on the keys was my first thought, and probably something I should have done in the first place. I guess I'd have to be pretty careful about how I handle the error it would generate though because I don't want:

a) Duplicate records to still be added to the usersVotedIn array anyways (while this shouldn't actually affect anything in practice it will still annoy the gently caress out of me to know that it's happening).

b) If it tries to add a duplicate and the request "fails" (despite their vote actually being recorded) the user will think that their vote did not count and the front-end would also not allow them to attempt to vote again.

Unfortunately, trapping constraint exceptions in Spring is a massive pain in the rear end - if you're using @Transactional, you can't catch them inside your service class, they have to be caught and turned into the appropriate HTTP response at the controller level.

Argyle Gargoyle
Apr 1, 2009

ABSTRACT SHAPES CREW

So my post-secondary group and I are about to graduate the program in about a week but we're having massive difficulty figuring out what should be an incredibly easy problem to solve for our final project.

We have a JSP-based website and we've wasted days trying to connect it properly, via servlet, to our individually locally-hosted Oracle databases.

Ultimately, where we're at is trying to figure out why we're getting a blank screen when pointing to our servlet and we are basically stuck so I gotta reach out to Java COBOL goons to ask: anybody mind giving me personal help resolving this problem? Our school expected us to be able to implement this with essentially zero instruction and it's coming down to the wire. I cant find a solution on Google and Im just lost at this point with what the minor thing is that we're missing that's causing this.

Adbot
ADBOT LOVES YOU

Pedestrian Xing
Jul 19, 2007

Argyle Gargoyle posted:

We have a JSP-based website and we've wasted days trying to connect it properly, via servlet, to our individually locally-hosted Oracle databases.

Are you using raw JDBC or an ORM? Are there any logs coming out of the driver?

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