-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathproblemsFaced.txt
More file actions
146 lines (91 loc) · 9.26 KB
/
Copy pathproblemsFaced.txt
File metadata and controls
146 lines (91 loc) · 9.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
🎯 Perfect Interview Answer for "Hardest Challenge" Question:
Here's a compelling response that showcases your technical growth and problem-solving skills:
🔥 The Struggle: Inter-Service Authentication & Session Management
Your Answer:
"The most challenging part was designing secure inter-service authentication while maintaining session consistency across my microservices architecture. I had to solve how a user authenticated on MainServer could securely access the ChatService without compromising the anonymous counseling privacy requirements."
The Technical Problem:
"Initially, I tried passing the original JWT directly, but that exposed real user identities to the ChatService, violating the anonymous counseling principle. I also struggled with session validation - how does ChatService know if a session is legitimate without constantly querying MainServer, which would create performance bottlenecks?"
Your Solution (Shows Growth):
"I solved it by implementing a dual-JWT strategy: MainServer generates a chat-specific JWT containing anonymous IDs and session permissions, signed with a shared secret. This way, ChatService can independently validate sessions without exposing real identities or creating database dependencies."
Additional Challenges You Overcame:
"This led to other complex decisions: How do I handle JWT expiry across services? How do I ensure URL and JWT session IDs match for security? How do I manage Redis TTL cleanup without losing important conversations? Each solution created new architectural questions that taught me about distributed system design."
🏆 Why This Answer Impresses Recruiters:
Shows Technical Depth:
✅ Security considerations (privacy, authentication)
✅ Performance thinking (avoiding bottlenecks)
✅ System design skills (microservices communication)
✅ Problem evolution (one solution creates new challenges)
Demonstrates Growth Mindset:
✅ Learning from mistakes (initial approach didn't work)
✅ Iterative improvement (refined the solution)
✅ Architectural thinking (considering trade-offs)
✅ Production considerations (security, performance, privacy)
🎯 Alternative Struggles You Could Mention:
Option 2: Real-time Architecture Complexity
"Designing the real-time messaging flow was incredibly complex. I needed to handle online/offline users, message persistence, push notifications for offline users, and Redis pub/sub - all while ensuring messages aren't lost and users get seamless experience regardless of connectivity."
Option 3: Data Management Strategy
"The hardest decision was choosing between Redis and MongoDB for chat storage. I initially went with MongoDB for simplicity, but realized I needed Redis for performance and TTL cleanup. Designing a hybrid approach that leverages both databases for their strengths while maintaining data consistency was really challenging."
Option 4: Privacy-First Architecture
"Implementing true anonymity while maintaining counselor effectiveness was the biggest challenge. I had to design anonymous ID systems, ensure ChatService never sees real identities, while still allowing counselors to track student progress through LLM summaries - all without breaking privacy guarantees."
💡 Follow-up Questions You'll Handle Well:
"How did you solve it?"
→ Technical explanation of your dual-JWT approach
"What would you do differently?"
→ "I'd implement more comprehensive testing for edge cases and consider using API Gateway patterns for better service orchestration"
"What did you learn?"
→ "Distributed systems are incredibly complex - every architectural decision has cascading effects. I learned to think about security, performance, and maintainability from the start, not as afterthoughts."
🚀 Key Messaging:
Complex technical problem (not just coding, but architecture)
Multiple failed approaches (shows persistence)
Elegant final solution (demonstrates growth)
Broader learnings (applicable to other projects)
This positions you as someone who tackles hard problems, learns from mistakes, and thinks about production-ready solutions - exactly what senior engineers and technical leads want to see! 🎯
"This led to other challenging decisions: How do I ensure the JWT and WebSocket URL session IDs match for security? How do I handle different expiry times across services? How do I manage session cleanup and data consistency between services? Each solution created new architectural questions that taught me about distributed system design and security boundaries."
ANswer this for me
🏆 Your Interview Answer Update:
"Yes, exactly! I implemented a two-tier JWT system: a long-lived personal JWT for general app access, and short-lived chat session JWTs that get refreshed periodically. The chat JWT can be re-signed with a new expiry time for refresh. Sessions persist until they're either archived by admin, expire from inactivity, or are manually ended by participants. During this time, I proactively refresh the chat JWT every hour to maintain seamless user experience, while the personal JWT validates the user's right to refresh the chat token."
problems Faced:
The hard parts were dealing with architecture decisions around inter-service authentication, session management. The user shouldn't unnecessarily need to log in to the chat service, just because they're using a microservice of the distributed system.
I had to figure out how to securely pass user sessions between MainServer and ChatService without exposing real identities, while also managing JWT expiry and session consistency across services.
The solution was creating a shared JWT system where MainServer issues a long-lived JWT for general app access, and ChatService generates short-lived chat session JWTs that are signed with a shared secret. This way, ChatService can validate sessions independently without exposing user identities, while also allowing for session management like expiry and refresh.
There were additional problems like the edge cases of session expiry, when the the user is using the service.
The solution was me implementing a system where the chatSession checks for session validity if it there is less than a few hours to the expiry of the token, it automatically refreshes the JWT token.
ChatGPT version:
In the microservice-based chat system I designed, the MainServer handles authentication and session creation (i.e., sign-in, creating a new chat room, assigning session IDs, etc.), while the ChatService running on a separate server is responsible for real-time message handling via WebSockets.
The challenge was:
How do I securely and efficiently pass authority from the MainServer to the ChatService?
How do I ensure that only the valid authenticated client, and not an impersonator or attacker, is allowed to initiate a WebSocket session with the ChatService?
How do I avoid multiple redundant verifications, extra lookups, or inefficient polling/handshaking mechanisms between the services?
⚙️ My Solution (Efficient + Secure)
🔐 JWT-based Handshake Token with TTL
When the client initiates a chat session by calling POST /chat/createSession, the MainServer:
Generates a short-lived JWT (e.g., sessionToken) containing the sessionId, userId, and possibly other metadata.
Stores this session in Redis with a TTL (e.g., 10 minutes).
Returns the sessionToken to the client.
When the client connects to the ChatService WebSocket, they must:
Provide the sessionToken as a query parameter or in headers during the initial WebSocket handshake.
The ChatService, upon WebSocket connection:
Verifies the JWT using the same secret/public key used by the MainServer.
Optionally checks Redis for session existence (to ensure it hasn't expired or been revoked).
Once verified, it establishes the socket connection and binds the user to their session.
🔑 Key Technical Choices & Benefits
Feature Explanation
JWT Self-contained, tamper-proof token carrying auth data. No need to call MainServer again.
Redis TTL Ensures automatic expiry of sessions, prevents stale sessions.
One-Time JWT (if needed) Can design it to be single-use (i.e., remove from Redis once used).
No Polling / Lookup Avoids unnecessary HTTP calls or DB lookups.
Separation of Concerns ChatService doesn’t need to understand MainServer internals.
📌 Framing it in an Interview
"I had to design secure communication between two microservices — the MainServer for authentication and a ChatService that ran WebSockets on a different port/server. Instead of depending on repeated DB lookups or insecure open sockets, I created a short-lived JWT on session creation, stored it in Redis with a TTL, and used it for a one-time secure handshake at the WebSocket layer. This kept the system scalable, stateless, and secure, while allowing the services to remain independently deployable."
💬 Your Question:
“Is this a good way or substandard/flawed?”
🟢 Pros (Strong Architecture)
✅ Scales well.
✅ Stateless token-based security.
✅ Minimal inter-service coupling.
✅ Good use of Redis for ephemeral state.
✅ JWT validation is fast and local to each service.
🔴 Possible Pitfalls / Improvements
⛔ If JWT secrets change or rotate, it must be managed carefully across services.
⛔ If Redis goes down, verification via token reuse must be carefully handled.
🟡 Consider using opaque tokens + Redis lookup instead of JWTs if you need better revocation control (but you lose statelessness).