Win a copy of The Java Performance Companion this week in the Performance forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Interview Question -- How to implement the login functionality in a Servlet.

 
Yuvi Gupta
Greenhorn
Posts: 20
C++ Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
thanks guyz, i have one more question which was asked by same interviewer.
Question was, You need to implement simple login functionality in servlet, if a user enter wrong password three times then lock the account. suppose i entered two times wrong password today and attempt third wrong one tomorrow then account must be locked. how you will maintain the counter??

My Answers was:
1. I can implement by maintain cookie but it is unreliable so i would not like to use it.
2. I can maintain counter in DB then he said i don't want to interact with database.
3. My last solution was that i'll maintain counter in session and i'll maintain the same session till the successful login or till the user attempt three times wrong password.
but again he was not satisfied by my answer. is there is any other way to achieve the functionality??
 
Winston Gutkowski
Bartender
Pie
Posts: 10427
63
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yuvi Gupta wrote:2. I can maintain counter in DB then he said i don't want to interact with database.

Sounds like this guy is just mucking you about and making up rules as he goes along, because that's exactly the answer I would have given:
A database table with a key of date (or timestamp) + loginId, and a counter.

I'm not well up on servlet technology, but I suspect that almost any other solution would be prone to hacks.

Winston
 
Tim Cooke
Sheriff
Pie
Posts: 3070
127
Clojure IntelliJ IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If he says he doesn't want to interact with the database then I would have asked him how he intends to look up the login user and password hash. You're going to have to hit the db to look up the user so why not maintain a count on the same table while you're there. Very small cost involved doing that so no reason not to.

Does sound like he's rejecting perfectly good answers just for the craic.
 
Chan Ag
Rancher
Posts: 1089
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I agree with Tim and Winston on the second question. But just for the sake of answering the interviewer, how about caching this data? ( This is really a question ).
 
Roel De Nijs
Sheriff
Posts: 10225
129
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yuvi Gupta wrote:is there is any other way to achieve the functionality??

You have some alternatives:
  • you can use a map with userId, numberOfAttempts pairs (memory issues can/will occur)
  • you can use a caching solution (like EhCache) to solve the memory issues from the previous one
  • you can create for each user a file (e.g. userId.txt) and store the numberOfAttemps (nothing was said about performance )


  • If this question was meant to test your ability to think out of the box, you can even have a solution without maintaining the counter. Something like:


    I know this solution does not scale very good and I definitely have to make it thread-safe. But I thought out of the box, mission accomplished
     
    Tim Cooke
    Sheriff
    Pie
    Posts: 3070
    127
    Clojure IntelliJ IDE Java
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    In memory caching is a variation on the same "persistence" theme and it would be impossible to guarantee a cache hit at any point in time.

    If you took it one step further and had only in memory persistence then you would never have a db hit, although technically you might still call that a database. But the problem with that approach is sharing that state across multiple application servers becomes non trivial quite quickly.
     
    Chan Ag
    Rancher
    Posts: 1089
    14
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    If you took it one step further and had only in memory persistence then you would never have a db hit, although technically you might still call that a database. But the problem with that approach is sharing that state across multiple application servers becomes non trivial quite quickly.


    The cache model would change depending on the design... Of course you've got to update the cache with every db update so you have to design the cache layer carefully( considering performance and all ).

    We are currently working on making our application support multiple tenants ( and servers and clusters etc ) and we have had to change our cache layer accordingly. I think if the application is really designed well, this should not be an issue.
     
    Campbell Ritchie
    Sheriff
    Pie
    Posts: 49411
    62
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Moved as too difficult for “beginning”.
     
    Winston Gutkowski
    Bartender
    Pie
    Posts: 10427
    63
    Eclipse IDE Hibernate Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Roel De Nijs wrote:You have some alternatives:
  • you can use a map with userId, numberOfAttempts pairs (memory issues can/will occur)
  • ...

    Actually, I'm not at all sure that you can (although I'd be happy to be proved wrong), because I regard the keyword in that spec as "today" (which I assume to be 24 hours), which could span multiple invocations of the login on separate clients, and possibly even multiple versions of the app itself (25/8 is really only a reality for the very rich, even now; and I doubt the rich would be worried about a trifling db access ).

    But like I say, if someone can let me know that a simple, memory-based solution exists, I'd be happy to retract my statement.

    Winston
     
    Paul Clapham
    Sheriff
    Posts: 21137
    32
    Eclipse IDE Firefox Browser MySQL Database
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Don't forget that your memory-based system has to survive a potential restart of the server software and even a potential reboot of the server hardware; that's assuming there is only one server and not a cluster of them.
     
    Roel De Nijs
    Sheriff
    Posts: 10225
    129
    AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Winston Gutkowski wrote:But like I say, if someone can let me know that a simple, memory-based solution exists, I'd be happy to retract my statement.

    Maybe I am oversimplifying things (that's just because I'm a true KISS principle advocate ), but I don't get why a simple in-memory solution would not be enough to solve this use case You need to implement simple login functionality in servlet, if a user enter wrong password three times then lock the account. 3 wrong logins = lock account, there is no time frame involved. This is just about a possible alternative to solve the interview question, ignoring all possible drawbacks of an in-memory solution (restart web container and/or server, out of memory, more than 1 server handling requests,...)
     
    Winston Gutkowski
    Bartender
    Pie
    Posts: 10427
    63
    Eclipse IDE Hibernate Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Roel De Nijs wrote:Maybe I am oversimplifying things (that's just because I'm a true KISS principle advocate ), but I don't get why a simple in-memory solution would not be enough to solve this use case You need to implement simple login functionality in servlet, if a user enter wrong password three times then lock the account. 3 wrong logins = lock account, there is no time frame involved.

    Fine, but how do you store that count in memory and guarantee its survival between multiple invocations of either client or server? If you can't, then someone can just keep invoking the client, trying twice each time, and break your "three strikes and you're out" rule.

    Winston
     
    Roel De Nijs
    Sheriff
    Posts: 10225
    129
    AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Winston Gutkowski wrote:Fine, but how do you store that count in memory and guarantee its survival between multiple invocations of either client or server?

    If you make accessing (and mutating) the map (holding the userId and numberOfAttempts pairs) thread-safe multiple invocations of the client should not be any problem at all.

    Having multiple servers is a complete different problem and requires another solution, such as Hazelcast for example (an open source clustering and distributed caching solution). I saw a presentation on Devoxx (in 2012 I believe) and it looked very promising, powerful and fast. The API is easy and very similar to the interfaces you know from the Java Collections framework (Map, Set, List,...).
     
    Winston Gutkowski
    Bartender
    Pie
    Posts: 10427
    63
    Eclipse IDE Hibernate Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Roel De Nijs wrote:If you make accessing (and mutating) the map (holding the userId and numberOfAttempts pairs) thread-safe multiple invocations of the client should not be any problem at all.

    I'm not sure that we're talking about the same thing. Thread-safety is not the issue; process (or servlet, or cookie, or session) lifetime is. If we are talking about a memory-based solution, then the lifetime of that memory MUST be guaranteed. If I log onto a web-based system, attempt two logins, then close my window, shut down (and possibly purge) my browser, and maybe even reboot my system, does your solution guarantee that my "memory-based" count is still 2 when I reconnect and attempt another login? If so, then the issue (as far as I'm concerned) is solved. If not: Houston, we have a problem.

    Winston
     
    Roel De Nijs
    Sheriff
    Posts: 10225
    129
    AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Winston Gutkowski wrote:
    Roel De Nijs wrote:If you make accessing (and mutating) the map (holding the userId and numberOfAttempts pairs) thread-safe multiple invocations of the client should not be any problem at all.

    If we are talking about a memory-based solution, then the lifetime of that memory MUST be guaranteed. If I log onto a web-based system, attempt two logins, then close my window, shut down (and possibly purge) my browser, and maybe even reboot my system, does your solution guarantee that my "memory-based" count is still 2 when I reconnect and attempt another login? If so, then the issue (as far as I'm concerned) is solved. If not: Houston, we have a problem.

    The LoginServlet resides on the server, so it's using the server's memory, not the client one. If you purge your browser and/or reboot your client system that would not be an issue at all.

    But you'll definitely have to handle a server reboot and (for a rock-solid solution) even a server's hardware crash. The 1st one is not that hard: you can implement a simple save-to-disk (on jvm shutdown) and read-from-disk (on servlet init) algorithm. The 2nd one is a lot harder to solve with a 100% guarantee. You could use the save-to-disk algorithm and run it periodically (e.g. each 5 minutes), but that would not be rock solid of course.
     
    Winston Gutkowski
    Bartender
    Pie
    Posts: 10427
    63
    Eclipse IDE Hibernate Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Roel De Nijs wrote:The LoginServlet resides on the server, so it's using the server's memory, not the client one. If you purge your browser and/or reboot your client system that would not be an issue at all.

    Oh, OK. Fair enough. I'm still not quite sure how the servlet engine would know that it's "you" re-establishing a connection in such a case; but I'm sure there's all sorts of clever goodies under the hood. [Edit: but I suppose if you're just using the server program's memory, that would actually be irrelevant, so forget my feeble mumblings.]

    I still reckon that a db solution is just as simple, though - and guaranteed to work whatever happens.

    Winston
     
    Roel De Nijs
    Sheriff
    Posts: 10225
    129
    AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Winston Gutkowski wrote:the servlet engine would know that it's "you" re-establishing a connection in such a case

    Because of the unique user name you have to enter in the login screen. That would be no different for the db solution...

    Winston Gutkowski wrote:I still reckon that a db solution is just as simple,

    I would even say the db solution is much simpler (because you don't need to handle server reboot or hardware crashes).
     
    Raghavan Muthu
    Ranch Hand
    Posts: 3381
    Mac MySQL Database Tomcat Server
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    If db call is not allowed, I would prefer relying on the ServletContext (a common memory) used by the Web Container for an application, which is an easy and simple way. However, should there be a application/server restart, your counter is gone!
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic