Naive string compression
The main problem IMO is, that you cram it all into a single method which is not helpful to organize your thoughts.

When I tried this for comparison, I came up with the following in pseudo code:

// outer logic
compress(s)
    rle = doRunLengthEncoding(s)
    if rle.length &lt; s.length return rle
    else return s

// base algorithm
doRunLengthEncoding(s)
    res = empty String buffer
    char[] characters = s.toCharArray
    int startIndex = 0
    while startIndex &lt; characters.length
        int endIndex = findEndOfCurrentSequence(startIndex, characters)
        res.append(currentChar).append(endIndex - startIndex)
        startIndex = endIndex
    return res

// return the first index i, where c[i] != c[start], return
// c.length if there is no such index
findEndOfCurrentSequence(start, c)
    ... // simple enough


This way, you divide the problem into manageble pieces, give you thoughts a place to stop every once in a while, and should get rid of this nervousness.

BTW: from an interviewer's point of view (at least I you want into my team in my country ;-)) a well thought pseudocode algorithm is worth more than working code. If you apply for a programmer's job, I just assume that you have the basic skills to use an IDE and kick against some piece of code until it compiles and produces the correct result. What I am looking for is organized thoughts and problem solving skills.

One last thing: there is one and only one correct exception to throw for a null parameter that must not be null: NullPointerException. Ideally by simply using Objects.requireNonNull.