so in a multithreaded program if i had my song class that was shared between two or more classes then they could possibly both have the ability to change song objects. then this could lead to the program not functioning correctly. If you have time and don't mind making an example I would love to see it.
It need not be a multi-threaded program. Mutation related bugs can slip in even for a single-threaded program though they are normally more painful and hard to find in case of a multi-threaded one.
As an example, let's say that you plan on providing a "replace" functionality to your users of the playlist class. So basically, they can pick an existing song from the playlist and replace it with a new one. If you resort to mutation (to save memory as they all say) and instead of creating a new song, try modifying the existing song, this is what happens:
MP3_Player ipod = null; // initialize with songs; assume
Song toRemoveSong = ipod.getSongByName("Hotel California");
// we need to maintain a list of removed songs
List<Song> removedSongs = new ArrayList<Song>();
removedSongs.add(exisingSong);
// In some other method; try replacing the song
Song oldSong = ipod.getSongByName("Hotel California");
oldSong.setTitle("Baby");
oldSong.setArtist("Justin Bieber");
// Show the songs user has removed from the ipod
showToUser(removedSongs);
In case you haven't noticed yet, we are hosed. Since Song is mutable, the list of removed songs now contains 'Baby' instead of 'Hotel California' and you have lost the song which you actually removed. This might sound like a trivial or maybe even a poorly fabricated example but this does happen in real code. For a small code base, it might not take a lot of effort but as code-base grows, you are in for some sleepless nights.
On a related note, shared static state is your worst enemy when it comes to multi-threaded code. As an example:
// parse Person objects from a text file; one line per person
class PersonParser {
public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
public Person parsePerson(String line) {
// parse date of birth using the static SimpleDateFormat above
// and other details. Return after creating a Person object
}
}
Now let's say I need to speed up the parsing and so decide to use multiple threads when parsing the text file or array of strings. Again, in case you haven't noticed, we are hosed. Why? Because SimpleDateFormat has its own internal mutable state. If we use it across threads, state trampling might occur which in turn would give wrong results or if you are lucky an exception. These kinds of bugs are really hard to find because your program might seem to be working but it really isn't.
Hopefully those are good enough examples to give you a brief overview of the kind of havoc uncontrolled mutation and state sharing can cause.
~s.o.s~
Failure as a human
12,220 posts since Jun 2006
Reputation Points: 3,307
Solved Threads: 783
Skill Endorsements: 55
I do have one thing to ask though just for clarification on point 4. I think I understand but you mean that I should lean more towards using the constructor than using the mutator methods?
Yes. So instead of:
Person p = new Person();
p.setName("sos");
p.setAge(666);
prefer
Person p = new Person("sos", 666);
To add to this, if you don't plan on changing the fields after the object is created, you can also mark them as final and be rest assured that there won't be any accidental assignment or mutation to these fields. It doesn't make a lot of difference in a single threaded program but become really important when you start using threads. Shared mutable state (i.e. sharing a Person object between two threads wherein the fields are mutate/can be set) can lead to headaches as the system grows in size. So for e.g. if you are asked to add a new song to the playlist and remove an existing one, instead of "mutating" or modifying the object you plan on removing, it's better to actually remove a given song object and add a new one. In short, stay away from unnecessary mutation! If you want to know more or need a detailed snippet to showcase the problem, just let me know and I'll write it out for you.
Does that come with the netbeans installation or is it a plugin that I can install seperately?
Some IDE's like Eclipse come pre-installed with JUnit 4 framework (make sure you use the latest JUnit version, the one which supports annotations). I think that's also the case with Netbeans. Here is a document which might help you out.
~s.o.s~
Failure as a human
12,220 posts since Jun 2006
Reputation Points: 3,307
Solved Threads: 783
Skill Endorsements: 55
A few more if you are game:
- Use camel casing when naming methods/classes/variables etc. as opposed to snake case (e.g. MP3Player as opposed to MP3_Player)
- Don't blindly provide getters and setters for every field in your class. For e.g. you already have
addSong and removeSong methods in your code; why provide a getter for songList. This is made worse by the fact that since songList is mutable, I can add/remove songs without triggering your checks which is not a good thing. If you still have to provide a list of all the songs, wrap up your list in an immutable wrapper which the user can iterate but not mutate.
- Think twice before adding methods; for e.g. why do you need a default constructor for MP3_Player?
- Favor constructor initialization over setters
- Be extra careful when validating user input. Currently you check for blank titles i.e. "". What happens if I pass in " "? Is that a valid title? If not, does your code catch that?
- Try out testing frameworks like JUnit for testing/validating your code.
~s.o.s~
Failure as a human
12,220 posts since Jun 2006
Reputation Points: 3,307
Solved Threads: 783
Skill Endorsements: 55
Does it still fail; it shouldn't fail. What does your new XML look like?
~s.o.s~
Failure as a human
12,220 posts since Jun 2006
Reputation Points: 3,307
Solved Threads: 783
Skill Endorsements: 55
You need to think why a code is written before adding in code. When you write: hello helloworld = (hello) context.getBean("helloworld");, what are you expecting it to return back? How do you think Spring will get back the hello object for you?
Take a few minutes and read the error message carefully. The error basically means "the context XML file which you have loaded doesn't have a bean called 'helloworld'" which is correct. Now the question is how can we fix this error? You already have defined a bean in the XML file but it isn't named "helloworld". How do you think can we do away with this error? Can you think of a way of replacing or modifying the code such that your class Main works?
On a related note, always put your class in package and follow Java coding conventions. hello is not a good name for a class. Also put this and the Main class in some sort of a package like test.
~s.o.s~
Failure as a human
12,220 posts since Jun 2006
Reputation Points: 3,307
Solved Threads: 783
Skill Endorsements: 55
I no longer program in Spring but IIRC, id names in Spring follow the Java variable naming conventions and hence ids can't be just numbers (which is what the exception message is trying to convey here). Change id="1" to id="one" and see how it goes.
~s.o.s~
Failure as a human
12,220 posts since Jun 2006
Reputation Points: 3,307
Solved Threads: 783
Skill Endorsements: 55
StoreReporter.class.getResourceAsStream doesn't do what you expect it to do. It tries to load a resource and return the corresponding stream relative to the class. Replace it with a new File(yourpath) and let us know how it goes.
~s.o.s~
Failure as a human
12,220 posts since Jun 2006
Reputation Points: 3,307
Solved Threads: 783
Skill Endorsements: 55
Which IDE are you using for development? Use a debugger a check why that line has a null root. The assignment on line 56 seems to be causing the problem because you don't do a null check on the root before using it on line 49.
~s.o.s~
Failure as a human
12,220 posts since Jun 2006
Reputation Points: 3,307
Solved Threads: 783
Skill Endorsements: 55
Trace your algorithm on a piece of paper before making changes. The code right now directly returns the left subtree node if the left sub-tree is non-null, something which is not desirable. Your top two conditions (the first two if's in the search function) are correct. The third if..else needs to be replaced by two if's. Something like:
- If left sub-tree is not null, search left sub-tree (you had this correct in the previous attempt)
- If right sub-tree is not null, search right sub-tree
- Return null if all else fails
~s.o.s~
Failure as a human
12,220 posts since Jun 2006
Reputation Points: 3,307
Solved Threads: 783
Skill Endorsements: 55
That's a good question!
JUnit and Servlets (basically your web apps) are frameworks. What a framework does is it runs the code you write which adheres to some common guidelines (e.g. in the case of a JUnit test, you either extend the class with some JUnit class or decorate the methods with the @Test annotation).
As to how it happens, its done entirely via reflection in both the cases. JUnit has the concept of "runners" or basically classes which run the test code. When you right click on the file and say run as JUnit test case, the Eclipse JUnit plugin calls one of the runner classes (in case of Eclipse BlockJUnit4ClassRunner) with the fully qualified name of your class to be tested. After that, it's all reflection magic by creating an instance of your test class, grabbing the special JUnit methods and executing them in some sort of wrapper/controlled environment.
In case of web apps, you specify the servlet fully qualified name of the servlet class in the web.xml file. The servlet container takes this name, tries to load and instantiate the class dynamically and if it succeeds, casts the object an appropriate servlet type (e.g. HttpServlet). I know this is all hand-waving and the details might deviate but the general idea remains the same. The web container/servlet container is very much aware of all the applications you have deployed, the URL's it is supposed to handle, the mapping between a given URL and a servlet etc. Thus, when a container starts, it loads up all this data and inside the main method (which is responsible for starting up the container), sets up a procedure which can handle requests at a given port and other things (which are specified in the servlet.xml file I believe).
Hope that explains stuff a bit.
EDIT: The bit about finding out which classes are executing your code, it's pretty simple. Just throw an exception in your code and the exception trace will show all the guilty classes involved in the entire process. This might not work always in case someone decides to mess around with strack traces but it works most of the time. For e.g. throwing an exception in my JUnit code gives me the following trace:
java.lang.RuntimeException: HI
at sos.TestMe.test(TestMe.java:11)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
From the above, it's pretty easy to see that it is the Eclipse plugin code which gets executed first, followed by the BlockJUnit4ClassRunner (note that ParentRunner is the super-classs of BlockJUnit4ClassRunner).
~s.o.s~
Failure as a human
12,220 posts since Jun 2006
Reputation Points: 3,307
Solved Threads: 783
Skill Endorsements: 55
Replace the else in the search method with another if statement which checks if the right sub-tree is not null and checks it.
~s.o.s~
Failure as a human
12,220 posts since Jun 2006
Reputation Points: 3,307
Solved Threads: 783
Skill Endorsements: 55
Now I have a problem with finding values on the right subtree.
I have added some code, that will search for a letter that was entered by the user, if it is found it will increase the frequency of the letter.
It will output for the root, and the left subtree, but does not return anything for the right subtree.
This is because you never search the right sub-tree if the value isn't found on the left sub-tree. You need to change your condition so that both left and right sub-trees are searched in your search method of the Tree class. Also, I hope you are aware that you lose the "find node in logarithmic time" feature offered by the search trees if you don't create your tree based on value but the number of nodes it has.
Another question.... Am I supposed to compare string values for the input for a balanced binary tree?
I'm not sure I understand this question: you are already searching for the nodes based on their string values?
~s.o.s~
Failure as a human
12,220 posts since Jun 2006
Reputation Points: 3,307
Solved Threads: 783
Skill Endorsements: 55
That's a pretty strange binary tree. Normally, insertion criteria is based on the "value" attribute of each node which helps you determine where to insert a node into a tree and at the same time, how to "search" for a node inside the given tree. With the number of nodes used as an insertion criteria, how do you plan on finding a given node in the tree?
Anyways back to the question; with the current code, the output of A B D F C E is expected. Trace the tree on a piece of paper for the input you suggested. What kind of tree do you get? Any reason why you think A B D E C F should be the output?
EDIT: Gah, replying to a stale thread...
~s.o.s~
Failure as a human
12,220 posts since Jun 2006
Reputation Points: 3,307
Solved Threads: 783
Skill Endorsements: 55
The documentation told me that base 10 was assumed if you didn't pass in the second argument!!
Oh noes, there is no such thing specified in the specification. The MDN goes to great lengths to even mention this:
An integer that represents the radix of the above mentioned string. Always specify this parameter to eliminate reader confusion and to guarantee predictable behavior. Different implementations produce different results when a radix is not specified.
:)
EDIT: If you plan on always dealing with base 10 numbers, using the Number constructor is a safer option.
~s.o.s~
Failure as a human
12,220 posts since Jun 2006
Reputation Points: 3,307
Solved Threads: 783
Skill Endorsements: 55
Moral of the story: Don't trust parseInt() to work the same in Firefox as it does in Chrome.
I'm really interested now, details please. And while we are at it, were you passing in the second argument to parseInt? If not, bad Dani. :)
~s.o.s~
Failure as a human
12,220 posts since Jun 2006
Reputation Points: 3,307
Solved Threads: 783
Skill Endorsements: 55
if one of the attributes of my class is a String, would that be an object inside my class???? Teacher says it's simply a variable...
There is no String inside your object. Keeping aside primitives for the time being, if a class is composed of multiple fields having different reference types (anything which derives from an Object), those names are nothing but references or pointers. There is no actual data being stored in your object. This distinction is important because you have the same object referred from multiple objects. If you think that a field is inside some other object, you might mistakenly think that each object has a copy of the field data which isn't true.
~s.o.s~
Failure as a human
12,220 posts since Jun 2006
Reputation Points: 3,307
Solved Threads: 783
Skill Endorsements: 55
~s.o.s~
Failure as a human
12,220 posts since Jun 2006
Reputation Points: 3,307
Solved Threads: 783
Skill Endorsements: 55
Creating new sub-forums is pretty much out of question these days since the focus/shift for the new Daniweb is more towards tagging stuff rather than creating new categories for things.
~s.o.s~
Failure as a human
12,220 posts since Jun 2006
Reputation Points: 3,307
Solved Threads: 783
Skill Endorsements: 55
I was wondering if a microcontroller or arduino section could have a home here. Or would that be best classified under "Software Development\C", or other various languages that can be used for more than 1 type of hardware?
Or Raspberry Pi, would that be a "Linux and Unix" thing, or something else?
There are multiple options. If you are writing it in C, posting it in the C section and adding a relevant "tag" should be good enough. Similarly with Python and other langauges; depends on the language your code snippet is in. Or, if your code is in a language which is not natively supported by this forum or it contains a dash of multiple languages, you can post it in the top level Software Development category and tag it accordingly.
~s.o.s~
Failure as a human
12,220 posts since Jun 2006
Reputation Points: 3,307
Solved Threads: 783
Skill Endorsements: 55
I have mixed emotions about it. What if I don't want the same avatar on all web sites that I visit?
Then maybe provide an option to override the gravatar image? But IMO this seems too much effort for something not too significant, especially when there are more important things to be tackled (chat, spell checker etc.). :)
~s.o.s~
Failure as a human
12,220 posts since Jun 2006
Reputation Points: 3,307
Solved Threads: 783
Skill Endorsements: 55