Path: csiph.com!usenet.pasdenom.info!news.albasani.net!.POSTED!not-for-mail From: Lew Newsgroups: comp.lang.java.programmer Subject: Re: multithreaded cache? Date: Wed, 23 May 2012 23:11:20 -0700 Organization: albasani.net Lines: 142 Message-ID: References: <4fb69812$0$6849$e4fe514c@news2.news.xs4all.nl> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Trace: news.albasani.net 6Oki5t+PgmWAJApldRATil9RdilADecbUSFAGTZNtNvxuTwx8Souv2mMr7cajibu/WkNRgMB0fdddOIXuQPjcKfvMrnDMeuO5ORLqfiUU176JxTdXSoJ/B4PyPg59KhA NNTP-Posting-Date: Thu, 24 May 2012 06:10:57 +0000 (UTC) Injection-Info: news.albasani.net; logging-data="8j4DTLuvSdAsCtASn0WccuAoit+VyTTv/i/ErG5bsyAQhfGnymNhQ0k/1yyE6Kk7BaQWQfNZJ79ocojM7Hs6gXesZQYrDkofFKAYqTCTaV3TM/vuZf69OPLO6lDEwEuE"; mail-complaints-to="abuse@albasani.net" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20120430 Thunderbird/12.0.1 In-Reply-To: Cancel-Lock: sha1:3En3PCD4yYx9a+TxUOnr6iKz/SM= Xref: csiph.com comp.lang.java.programmer:14765 Robert Klemme wrote: > Thanks for sharing that story. What I find amazing about this is that what you > did isn't exactly rocket science and yet they didn't do it before. You would > guess that it's just what every engineer would do but no: something prevents > this from happening. It was worse. Turns out the resource acquisition managed by the inter-thread map coulda woulda shoulda been handled better by an object instantiated with a simple new ..() call. The returned reference and access to the object would perforce have been limited to the instantiating thread. Any other thread woulda shoulda coulda had its own independent resource, object, reference, whatever. Sharing was not needed. Loosely speaking - Desirable desire = getFromMap(FANCY_CAR); // map is shared, with fancy-schmancy synch vs. Desirable desire = new FancyCar(); // Map? Meshugge! I'm not sharing! > And it is true for a number of other techniques I would consider bread and > butter tools: > > - Ensuring requirements are gathered properly and understood before starting > to code (and design of course). True, with provisos. = Requirements are not fixed. What you should have now is the best available for now. = "Properly"? "Understood"? There are books on this, but it boils down to: Your software will be used. By whom? Why? What would annoy them? Don't do that! What would make them forget the software is there and just get their job done? Do that! "Proper" is always from the user's standpoint. Not what they say, by the way, but what they think and feel - really. Behind the bullshit and self-deception, when they aren't posturing for your benefit and really are just trying to get their work done. And that's where "understood" comes in. Give'em what they want, not necessarily what they ask for. > - Testing code _before_ shipping. Some espouse before even writing it. I say, sure, great idea, when you make it easy to express my ideas in tests instead of imperative code. Hmm. BTW, this being Java, have you guys tried EasyMock? (AndroidMock in Android Java.) That shtuff rocks. It makes your very code better, not just tested but idiomatically. Tricky stuff. I'll post about that when I get back into it. I've discovered a Right Way and a Wrong Way to do mocks, just like I did with JPA. > - When writing unit tests, making sure to also include tests for critical > values (usually corner cases such as -1, 0, 1, limit, limit - 1, limit + 1, > null, "", etc.). Consider this. No matter what input a module receives, it must achieve a valid program state in response. No matter what. Coding to this formalism means, for example, that a method can handle all possible argument values. public interface Caromer { public Fromitz carom(Flamo flame); } As Herr Klemme points out, 'null' is one possible input for 'flame'. Non-'null' is another. Presumably a 'Flamo' has observable state that distinguishes input values. If the type were 'Integer' or 'int', Robert's example int values might pertain. But you cannot give infinite test cases to a unit test. So you pick edge cases, on both the "happy path" (positive) and "unhappy path" (negative) scenarios. Consider this: public interface Quadrupler { public int quadruple(int val); } What if it were called with an auto-unboxed Integer? public int someClient(Integer val) { Quadrupler quadrupler = QuadFactory.get(); Integer quadded = quadrupler.quadruple(val); } > - Thinking about the person who must use what you produce, regardless whether > it's a document, a configuration file layout, a DSL, a class, a library. It > seems many people in software development are far more concerned with the > inner workings of what they create instead of considering how it will be used. > Maybe it's easier or it is because making it work takes the largest part of > coding - still the outcome often is dissatisfying and a little more thought > upfront goes a long way at avoiding maintenance headaches and worse things. > > ... > > This can't be so difficult, can it? You have a fine sense of humor. It's as easy as empathy, and getting inside the mind of a professional in a field of which you know little to nothing. Testing certainly helps. Functional tests (as opposed to unit tests) can and should be part of and produced from requirements. At the user-facing level you can send test scenarios back as memos of understanding (MoUs) - what better way to make clear what you understand and how it will play out? Prototypes count, too. They can meet tests, even. Building a prototype that meets tests, starting within a day or so of starting, kicks ass for converging on clarity. Keep it up - every day the prototype runs, works (up to whatever you've done that day), can be checked out and run in any directory, by any developer, and run, etc. Add a CI tool like Jenkins to run your tests every time you "git commit" to "origin/master" (or whatever); you got yourself a one-entity professional shop. -- Lew Honi soit qui mal y pense. http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg