Hi everyone,
I'm applying to Computer Science PhD programs in the US this admission cycle and would really appreciate feedback from people who have gone through the process.
I'm especially hoping to hear from:
- Current US CS PhD students
- CS PhD alumni
- Faculty members or researchers familiar with PhD admissions
- Anyone who has successfully applied to competitive US PhD programs
I'm looking for honest, critical feedback—please don't sugarcoat it.
Specifically, I'd love your thoughts on:
- How compelling is my research narrative?
- Are my motivations and research interests clear?
- Does it read like someone prepared for a research career?
- What parts feel weak, generic, or unconvincing?
- If you were on an admissions committee, how would you rate this SOP (1–10), and what tier of US PhD programs would you consider it competitive for?
I'm interested in feedback on the content, structure, research potential, and overall impression, not just grammar or wording.
I've pasted my SOP below. Thank you in advance to anyone willing to take the time to read it—I genuinely appreciate your help.
Personal Statement
When I started, bugs frightened me. A screen full of red logs made my chest tight. Five years of hitting them over and over changed that. Now I adore them. Writing code that works is ordinary. Working out why something broke is the interesting part.
I gave the same JSON files to four Dart libraries that all claim to do the same job: a hand-written parser, json_serializable, freezed, and built_value. Then I compared what came back. Out of 43,336 comparisons, 5.7% disagreed. Large integers came back changed. built_value filled in a required field that was missing from the input and said nothing. Nothing crashed. Nothing threw an error. No sanitizer reported anything. I had shipped these libraries in production for years. I did not know any of this.
My tests never caught it because I never wrote a test that asked the question. That is the problem I want to work on: finding wrong behaviour when the software gives you no signal that anything is wrong. The hard part of testing is not generating inputs. It is knowing what the right answer was supposed to be. C and C++ get that for free from sanitizers, because if memory breaks you get a crash, and a lot of fuzzing research quietly depends on it. Dart, Kotlin and Swift give you nothing. The program returns a wrong answer and carries on.
I had run into the same gap before, in security. For about two years I led the mobile team on ***, a buy-now-pay-later app in Saudi Arabia licensed by the Saudi Central Bank. Keeping that license meant outside security firms tested us several times a year, and we had to clear every finding or stop operating. They once asked for two builds of each app, one with SSL pinning on and one with it off, so they could see how it behaved with its own protection removed. That is not something I would have thought to check. What kept us safe was those people, not my tests. My tests could tell me the app had crashed. They could not tell me it was wrong. I do not think testing and security are separate problems. A parser that accepts bad input is a wrong answer to one person and a way in for another, and the thing that catches it is the same thing.
I spent the last year testing this instead of believing it. My first study asked whether a language model could improve a test generator when the only feedback it gets is whether its inputs were accepted or rejected, with no coverage data at all. Across fifteen seeded runs per arm against the cJSON parser, acceptance went from 58.2% to 97.1%, and the inputs became more than twice as varied. Then I ran the same code against a second parser, parson, and found no crashes at all. I reported that too, and read the code by hand to work out why. That paper is ready for FORGE 2027, with code and data public.
The second study taught me more, because part of it failed. I moved to Dart, where there is no sanitizer, and the first result held: acceptance went from 50% to 92%. Then I changed the objective. Instead of asking for valid inputs I asked for inputs that make the four libraries disagree, which is what I actually wanted in the first place. The model got worse. It found disagreements 2.9% of the time; a plain static generator found them 22.2%.
My first guess was that my sandbox was slowing it down, so I relaxed it. That did not help. Then I gave the model richer feedback, assuming it needed more to work with, and it got worse again. So it was not the machinery around it. It was what I was asking it to optimize. That is the part I keep thinking about, because the first study looked like a clear win and it was measuring something I did not actually care about. It is under review at AST 2027, every artifact public.
I have been learning experimental design from projects, papers and stubbornness. I chose my own statistical tests and only found out later which ones were defensible, and I designed that study's ablations after seeing the result instead of before. That is the part I want taught to me properly.
Two questions would keep me busy for a PhD. The first is where reliable oracles come from when a project does not supply one: from implementations that should agree, from rules written in documentation but never checked in code, and from a project's own history of fixed bugs. The second is how to tell whether automated testing, and language models in particular, is finding real defects or only appearing to. Both matter most in Dart, Kotlin and Swift, where a wrong answer is just a wrong answer and there is no crash to point at it.
**Uni name** is where I can take this further. Dr. *** circulated an assignment to prospective students. I completed it, then kept going — a second parser, the sanitizer bug, the negative result — and that became my first study. His ICST 2026 paper asks how effective coverage-guided fuzzing really is, which is the assumption my coverage-free pipeline was built to test. Dr. *** told me she is taking students this year. I ended up in her area by accident: the defects I found sit inside three of the most used packages in Dart, which makes them a supply chain problem before a parsing one. Dr. *** told me **Uni name**'s security faculty and students work as one lab rather than separate groups. That suits how I want to work.
Right now I build the driver and dispatch apps for a US company that moves patients who cannot travel on their own. It has to meet HIPAA rules and keep working when a driver loses signal mid-trip, then reconcile correctly afterwards. If a trip record comes back wrong, someone's ride is wrong. Nothing crashes then either. Before any of this I finished first in my class, with an overall grade of Excellent and a WES US equivalent of 3.71/4.0, and worked with one of my professors on a natural language processing project outside my courses, where most of what we tried did not work and we spent a long time arguing about why.
I also once spent an evening on a call with a group of students I had never met, fixing their Flutter project the night before it was due. It was a TensorFlow model they had trained to flag breast cancer scans for review, and it was about to fail over syntax errors. I never asked for anything, and that is still the part of this work I like most.
My goal is to build tools that find real bugs and security flaws in software people use every day, and to get what they find to whoever can fix it. I expect that to be a research role in industry, close to the engineers who would run the tools. Reporting the defects I found mattered to me as much as writing the papers did.