|
Hippie Hedgehog posted:To be fair, Gradle has several of those good properties that you like in Bazel, like reproducible builds and great staleness checks. Sounds good, it's been a few years since I worked with Gradle, so the tool has probably improved since I used it. It's great that it does a good job with incremental builds. I think there's still a bit of a gap between Gradle and Bazel though, since Bazel runs build targets in a sandbox, which prevents access to any files you didn't declare as dependencies of the current target. This ensures that a build target is a pure function from declared inputs to declared outputs. That makes it a lot easier to ensure that features like incremental builds (and incremental tests), remote caching and remote execution behave correctly, since you can be sure that a build output or test result can be reused if the declared inputs didn't change. I think the Gradle people have discussed adding a sandboxed mode for the same reasons.
|
# ? Jun 6, 2022 10:51 |
|
|
# ? Jun 1, 2024 19:56 |
|
If given a large, lovely, monolithic project, are there any decent tools for creating graphs (class dependecy or method call) out of it and fiddling with them. Stuff like automatic clustering etc. I tried using IntelliJ diagrams but they're not really doing it for me.
|
# ? Jun 6, 2022 12:27 |
Is setting min & max heap sizes to the same value still a good idea? I guess performance concerns aside, even if those aren't a big issue anymore, it seems like it's still a good idea to set min=max since it's possible for the JVM to get to that point anyways, so why not start there from the get-go?
|
|
# ? Jun 8, 2022 19:44 |
|
It very much depends on the application. If you have a command-line utility then you probably don't need an 8GB heap just to print your usage message, you know? For long-running servlet-style applications then yeah it totally makes sense though.
|
# ? Jun 9, 2022 00:07 |
|
fletcher posted:Is setting min & max heap sizes to the same value still a good idea? If you're sure that the JVM won't get to that point then yes, it doesn't matter. But if it does, then there could be problems and how they're solved I guess it depends on the garbage collector and the amount of stress the application is under. Ideally you'd benchmark it, stress test it to figure out how your app will behave when it reaches the limit, can it free objects fast enough to still be responsive? Will it lock for seconds at a time? For IDEs I used to just put min=max to 4G or whatever and don't worry about it.
|
# ? Jun 9, 2022 01:40 |
Volguus posted:If you're sure that the JVM won't get to that point then yes, it doesn't matter I guess that's the main difference between my point of view and a colleague's. My thinking is that if min < max, then yes it's possible for it to get to max. Unlikely based on historical usage? Sure, but still technically possible for some unforeseen issue. My colleague's point of view is that since historical usage is that actual usage is so far below max that it's not necessary to have them set to the same value. I guess the point to be made there would then be, why are we so over-provisioned?
|
|
# ? Jun 9, 2022 02:13 |
|
What's the context of this application? If you have a server or container or w/e where this is the only thing running, you should definitely set it up to grab all the memory you've provisioned for it right away. It's not like that memory will be used for anything else anyway. If this is a desktop application, then you'll want a lower min value, because the user of your application will want to multitask with other memory-intensive things, rather than having your application hogging memory that it isn't using.
|
# ? Jun 9, 2022 02:31 |
Jabor posted:What's the context of this application? Oh yeah forgot to mention that! It's a web based Java application running on a server. For the vast majority of the servers, it's the only thing running on the server (aside from logstash, telegraf, etc). There's a few odd cron jobs here and there that consume memory at times as well, though I'm pushing to get those off the app servers. fletcher fucked around with this message at 08:02 on Jun 9, 2022 |
|
# ? Jun 9, 2022 02:36 |
|
loving around with Spring in some side projects to get a little more familiar and something I haven't been able to settle on is whether to use constructor params or the @Autowired annotation. Is there any reason to use one versus the other? I'm guessing there's probably some gotchas that I just don't know about yet.
|
# ? Jul 4, 2022 03:25 |
|
HamAdams posted:loving around with Spring in some side projects to get a little more familiar and something I haven't been able to settle on is whether to use constructor params or the @Autowired annotation. Is there any reason to use one versus the other? I'm guessing there's probably some gotchas that I just don't know about yet. I'd recommend using @Autowired on the constructor parameters rather than the fields directly. Makes it easier to build specific instances manually, makes the signature explicit, makes tests easier, etc. Also more options later if you want to change out the DI for another implementation like Dagger or Micronaut that pre-compiles. Just my opinion though. Objective Action fucked around with this message at 17:13 on Jul 4, 2022 |
# ? Jul 4, 2022 03:39 |
|
Agreed from a Kotlin perspective that services and controllers with constructor parameters is nice and easy to work with, especially when it's time to stuff a bunch of mocks into them during tests.
|
# ? Jul 4, 2022 05:22 |
|
Yeah, field injection seems like something most people decided was a bad design decision. “Let’s have private fields that are set via reflection!”
|
# ? Jul 4, 2022 15:41 |
|
Constructor injection has the additional benefit of making you think twice before you add the 15th parameter to that constructor. By that point you probably should have split your service already, as it does too much. On the other hand ... it's not the end of the world if you do private field injection. Try to avoid it though.
|
# ? Jul 4, 2022 15:47 |
|
all good points, thanks!
|
# ? Jul 4, 2022 16:15 |
|
Anyone know a good way to do handle result paging with CompletableFuture without potentially infinite recursion or just arbitrarily checking the depth? pseudocode: code:
|
# ? Aug 10, 2022 18:18 |
|
The easy way would be to query a non-paging variant of the API. You're not "handling" the paging in any meaningful sense, just bypassing it.
|
# ? Aug 10, 2022 18:44 |
|
MrQueasy posted:Anyone know a good way to do handle result paging with CompletableFuture without potentially infinite recursion or just arbitrarily checking the depth? Why would you want to call an async method recursively? If recursion needs to be used instead of a simple loop (which is what I'd go with here) then move the recursive code into a synchronous method called from the async methods.
|
# ? Aug 10, 2022 18:44 |
|
Jabor posted:The easy way would be to query a non-paging variant of the API. You're not "handling" the paging in any meaningful sense, just bypassing it. Lets imagine for a second that we're dealing with an api that does NOT have a non-paging variant. RandomBlue posted:Why would you want to call an async method recursively? If recursion needs to be used instead of a simple loop (which is what I'd go with here) then move the recursive code into a synchronous method called from the async methods. Can you clarify what you mean by this? I may be mistaken in how CompletedFuture works. If I do this in the normal blocking while loop way, it will block until all N pages load (of which there are sadly arbitrarily many... probably less than 100?). I would like to start up other downloads (that operate similarly) while I wait for these calls to resolve. The only way to tell if there are more pages is if there is a token. I can't just walk the pages and tell it to stop when it starts erroring. (Ugh... I've been in clojure too long... this stuff is relatively straightforward with lazy loading or tail-call optimization)
|
# ? Aug 10, 2022 19:01 |
|
MrQueasy posted:Can you clarify what you mean by this? I may be mistaken in how CompletedFuture works. I didn't realize the externalService.query() method was returning a CompletableFuture, so nevermind. I don't know what best practices for a use case like this are so I'll stop offering bad advice.
|
# ? Aug 10, 2022 19:33 |
|
MrQueasy posted:
Calling functions asynchronously like you're doing isn't going to blow out the thread stack, if that's what you're worried about. Each call to thenCompose() allocates a lambda on the heap with the current context, the thread stack never gets particularly deep unless the request somehow completes in between you calling query() and then calling thenCompose() on the result. If you're worried about that then you could call thenComposeAsync() instead.
|
# ? Aug 11, 2022 03:14 |
|
Jabor posted:Calling functions asynchronously like you're doing isn't going to blow out the thread stack, if that's what you're worried about. Each call to thenCompose() allocates a lambda on the heap with the current context, the thread stack never gets particularly deep unless the request somehow completes in between you calling query() and then calling thenCompose() on the result. If you're worried about that then you could call thenComposeAsync() instead. Thank you, this has taken a load off of my mind... (despite sending me down a rabbit hole about how and when to use the *async methods)
|
# ? Aug 12, 2022 00:59 |
|
Does anyone have any recommendations for generating an OpenAPI 2 / Swagger document from annotations using Spring Boot 2.6.x? We're currently stuck using OpenAPI 2 at work, and Springfox doesn't work with Spring Boot above 2.5.x.
|
# ? Aug 14, 2022 18:45 |
|
hooah posted:Does anyone have any recommendations for generating an OpenAPI 2 / Swagger document from annotations using Spring Boot 2.6.x? We're currently stuck using OpenAPI 2 at work, and Springfox doesn't work with Spring Boot above 2.5.x. I use https://springdoc.org/ but that's OpenAPI 3. To my knowledge the only option for 2.0 (that was anywhere near usable) was Springfox. If it absolutely has to be 2.0 I think your only option might be to check for forks or fork Springfox yourself?
|
# ? Aug 14, 2022 21:30 |
|
So I have a jar (two, actually which are unrelated) that I'm decompiling with quiltflower for 'fun' to make some changes. Seems to work mostly okay. I get a few non-fatal errors about failure to understand enums but for the most part I seem to get mostly real, if unreadable and stripped down, java out. There are a few problems though. 1) Every java file comes with a few megabytes of empty lines and random @ symbols lol. That's annoying but I was able to clean up the files to the point they were useable with sed. 2) The decompile seems to be incomplete with some variables and functions simply not having proper declarations?. 3) The pom.xml for some dependencies seems to be broken out of the box and I can't figure out how to even fix it because I don't understand Maven. 4) vscode seems to properly understand the project and allow me to jump between references and declarations easily for things that actually exist, but intellj does not. Are these just normal problems to be expected from using quiltflower? I can't even figure out how to learn to understand what I need to fix these problems. Like the fixing the maven issues. Some dependencies are fine like gson and logback-core, but logback classic is broken and referencing manifest files that don't exist. I clearly don't understand how to use my IDEs, either vscode or intellj properly either because I have different problems with each. Honestly if I could figure out how to actually get this to recompile, I could probably hack and cheat my way to my solution with enough time and breakpoints. Overall 0/10 experience. Only thing I've learned is how incompetent and in over my head I am. Methanar fucked around with this message at 01:04 on Aug 15, 2022 |
# ? Aug 15, 2022 01:02 |
|
Are those jars closed source? It could be the developer put stuff in to mess with decompilers, it could also be that Quiltflower seems to be specifically maintained by Minecraft modders. You might find it beneficial using other decompilers?
|
# ? Aug 15, 2022 11:07 |
|
You might try the Jetbrains decompiler? I've had success with that, it's pretty nice.
|
# ? Aug 15, 2022 13:50 |
|
Intellij has a built-in decompiler e:fb
|
# ? Aug 15, 2022 13:50 |
|
You can use it standalone, too. Someone pulled it out of the IntelliJ source tree https://github.com/fesh0r/fernflower
|
# ? Aug 15, 2022 14:44 |
|
Tesseraction posted:Are those jars closed source? It could be the developer put stuff in to mess with decompilers, it could also be that Quiltflower seems to be specifically maintained by Minecraft modders. You might find it beneficial using other decompilers? I did actually find upstream fernflower to be better. These jars are just obfuscated to all hell which is why I was so confused. Coming back to this a few days later with a somewhat cleaner head, I'm actually somewhat enjoying the tedious, repetitive uncreative process of deobfuscating for now. A few sed statements later and I was able to get reasonably sized java files out without several hundred megabytes of padding code:
code:
The first step has been to decode these into real values again. And then walk everything that calls the big array of obfuscated values with string replacing to get slightly more readable code. really just continuing that process of renaming things back to something readable, fixing weird decompiler type errors, removing dead code, removing obfuscator logic and making educated guesses about what function names should be based on what they are doing and the interfaces they implement. Some functions actually did decompile down to useful names, names of standard java libraries and the included 3rd party libraries, I guess my decompiler had the symbols handy somehow? Or maybe they didnt get obfuscated in the first place. Not sure on that one. Lucky for me, one of the internal packages included in this app did not get obfuscated properly so I have a full library of proper internal things with no obfuscation! There's still some unresolvable function names that I don't have the definitions for. I suspect this is because the internal package did not get obfuscated, the useless obfuscated undeclared ililil names are supposed to be referring to some class declared within that. For the int obfuscation, which is all just bit math, I am copy pasting the lines into a ruby interpreter because that's actually valid ruby and its just easiest way I could think to do it lol. I made my own little decoder tool for the nastier string decoding which is full of casting char to ints and bit mathing that and md5 poo poo. The decompiler seemed to have made a lot of type errors which is honestly not a great sign but intellj has been able to auto suggest what to do so whatever. But for now i'm just enjoying my tedium of decoding static ints and strings and guessing function names. I can't believe I am enjoying deobfuscating java. Methanar fucked around with this message at 06:31 on Aug 18, 2022 |
# ? Aug 18, 2022 06:28 |
|
For class, I have to program a recursive solution to the following word problem and I have no idea how. I'm not good at math puzzles. " A frog wants to cross a river that is 11 feet across. One side of the river -> stone1 -> stone2 -> stone3 -> stone4 -> stone5 -> stone6 -> stone7 -> stone8 -> stone9 -> stone10 -> the other side of the river. There are 10 stones in a line leading across the river, separated by 1 foot, and the frog is only ever able to jump either one foot or two feet forward to the next stone. In how many different ways can he jump exactly 11 feet to the other side of the river?" I have no idea how to go about this.
|
# ? Sep 9, 2022 01:46 |
|
Mycroft Holmes posted:For class, I have to program a recursive solution to the following word problem and I have no idea how. I'm not good at math puzzles. " A frog wants to cross a river that is 11 feet across. One side of the river -> stone1 -> stone2 -> stone3 -> stone4 -> stone5 -> stone6 -> stone7 -> stone8 -> stone9 -> stone10 -> the other side of the river. There are 10 stones in a line leading across the river, separated by 1 foot, and the frog is only ever able to jump either one foot or two feet forward to the next stone. In how many different ways can he jump exactly 11 feet to the other side of the river?" Does the class have a TA? Or have you talked to the professor at all? They should be able to help you at least wrap your brain around what the puzzle is asking. I've been coding for ~9 years (6 years professionally) and nothing comes to mind to me after 30 seconds, so this at least isn't trivial.
|
# ? Sep 9, 2022 01:56 |
|
A good way to start with this is to think about smaller problems. - If the river were only one foot across, how many ways would the frog be able to jump it? - If the river were only two feet across, how many ways? - Three feet across? - Four feet? These are small enough that you can work out the answers by hand easily enough, but after doing that you might be able to see a pattern that you can then apply to the full-scale problem.
|
# ? Sep 9, 2022 02:30 |
|
Yeah, think about how you would systematically write down every way you could cross. Then you transfer that method to a structure in your code and loop through it recursively.
|
# ? Sep 9, 2022 03:33 |
|
hooah posted:Does the class have a TA? Or have you talked to the professor at all? They should be able to help you at least wrap your brain around what the puzzle is asking. I've been coding for ~9 years (6 years professionally) and nothing comes to mind to me after 30 seconds, so this at least isn't trivial. The puzzle is asking you to come up with all possible configurations of adding 1 or 2 to make 11. The point of making it recursive is to make it so that the 11 is arbitrary, so you can't hard-code the solution after working it out by hand.
|
# ? Sep 9, 2022 12:13 |
|
Tesseraction posted:The puzzle is asking you to come up with all possible configurations of adding 1 or 2 to make 11. The point of making it recursive is to make it so that the 11 is arbitrary, so you can't hard-code the solution after working it out by hand. This is the kind of thing that makes me really glad I don't have to devise algorithms for my job. I do not miss this kind of crap from school.
|
# ? Sep 9, 2022 12:38 |
|
looked up the riddle. Turns out it's an example of the Fibonacci sequence, so I can now code that.
|
# ? Sep 9, 2022 13:00 |
|
If you wanted to identify it yourself without having to look it up, you can notice that there are really only two ways of reaching exactly distance n: - You get to exactly distance n-1, then take a one-foot hop - You get to exactly distance n-2, then take a two-foot hop So the total number of different ways is the number of different ways to get to exactly n-1, plus the number of different ways to get to exactly n-2, which is the definition of the fibonacci sequence.
|
# ? Sep 9, 2022 13:09 |
|
Mycroft Holmes posted:For class, I have to program a recursive solution to the following word problem and I have no idea how. I'm not good at math puzzles. " A frog wants to cross a river that is 11 feet across. One side of the river -> stone1 -> stone2 -> stone3 -> stone4 -> stone5 -> stone6 -> stone7 -> stone8 -> stone9 -> stone10 -> the other side of the river. There are 10 stones in a line leading across the river, separated by 1 foot, and the frog is only ever able to jump either one foot or two feet forward to the next stone. In how many different ways can he jump exactly 11 feet to the other side of the river?" Every recursive solution works the same way. 1. Check to see if you have solved the problem. If you have, output the answer and stop. 2. If you haven't, identify a way to turn the current problem into subproblems. 3. Then start solving the subproblems. 4. Repeat. So here: 1. Have you outputted all possible ways to complete your solution? Here you only end when you get to stone 10 (1 way to jump to the other side of the river) or the other side of the river (0 ways to jump to the other side of the river). In this case your function countRiverCrossings(stone10, river) returns 1 and your function countRiverCrossings(river) returns 0. 2. If no, how many possible solutions do you have from where you start? Well, if your function is something like countRiverCrossings(river, stone1, stone 2, [etc], river), then you know that from the river the frog can only jump to either stone 1 or stone 2, right? So your answer of total ways is...0 (your current result) + countRiverCrossings(stone1, stone2, [etc], river) (this assumes the frog jumps to stone 1) + countRiverCrossings(stone2, [etc], river) (this assumes the frog jumps directly to stone 2).
|
# ? Sep 9, 2022 19:58 |
|
Somebody in this forum (can't remember which thread) once said that all recursive algorithms can also be expressed as a while(true) loop with a manual break condition and it really made them way easier to approach.
|
# ? Sep 10, 2022 00:25 |
|
|
# ? Jun 1, 2024 19:56 |
|
Pedestrian Xing posted:Somebody in this forum (can't remember which thread) once said that all recursive algorithms can also be expressed as a while(true) loop with a manual break condition and it really made them way easier to approach. Yeah, that's the same concept, although it isn't as clear about "solve all the obvious subproblems" and turning a recursive algorithm into a while(true) is often going to require a lot of list manipulation to manage your intermediate results.
|
# ? Sep 10, 2022 00:33 |