程序员老鬼

不尊重人的候选人,凭什么给你机会,候选人因低于他期望的40W。我也直说了公司只能给35万,他表示不接受。。

这候选人也挺会给自己加戏的。

公司开到35万,他心里想要40万,不接受,这没毛病。谈薪嘛,大家都想多拿点,嫌低就走,很正常。

但问题是,你当时那个态度如果已经摆出来了,几天后发现外面没更好的,又回头找HR说“我可以接受了”,这就有点尴尬了。

Image

前面嫌人家给少了,转头没人接盘,又回来想捡起来,这不是谈判,这是把公司当候补选项。

HR拒了也很正常。招聘不是菜市场砍价,岗位流程一旦重新启动,别人也要继续筛简历、约面试、走审批。你这边突然回头,人家凭什么停下来等你?

有些人总觉得机会是摆在那儿的,想要就拿,不想要就先晾着。可公司也会看态度的。能力重要,但合作感也重要。还没入职就这么拧巴,真进来了,估计也不好伺候。

今日面试题

输入是这样的:

"  hello   java   world  "

结果要变成:

"world java hello"

这题别急着 split(" "),我一般第一眼就不太信这种写法。不是不能过,是它把很多脏活都藏起来了:前后空格、连续空格、临时数组、字符串拼接,一多起来代码看着简单,实际分配了一堆对象。

这题真正要处理的就三件事:

把多余空格清掉,只保留单词之间一个空格。

把整个字符串翻转。

再把每个单词单独翻回来。

比如:

hello java world

整串翻转后是:

dlrow avaj olleh

这时候单词顺序已经对了,只是每个单词内部反了。再逐个翻回来:

world java hello

代码我会这么写,短一点,逻辑也比较直:

classSolution{

public String reverseWords(String s){
if (s == null || s.length() == 0) {
return"";
        }

char[] cleaned = cleanBlank(s);
if (cleaned.length == 0) {
return"";
        }

        reverse(cleaned, 0, cleaned.length - 1);

int left = 0;
for (int right = 0; right <= cleaned.length; right++) {
if (right == cleaned.length || cleaned[right] == ' ') {
                reverse(cleaned, left, right - 1);
                left = right + 1;
            }
        }

returnnew String(cleaned);
    }

privatechar[] cleanBlank(String s) {
        StringBuilder box = new StringBuilder(s.length());
boolean needSpace = false;

for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);

if (ch == ' ') {
if (box.length() > 0) {
                    needSpace = true;
                }
continue;
            }

if (needSpace) {
                box.append(' ');
                needSpace = false;
            }

            box.append(ch);
        }

return box.toString().toCharArray();
    }

privatevoidreverse(char[] arr, int l, int r){
while (l < r) {
char tmp = arr[l];
            arr[l] = arr[r];
            arr[r] = tmp;
            l++;
            r--;
        }
    }
}

这里最容易写歪的是清理空格。

有些人会先 trim(),再 split("\\s+"),最后再拼回去。面试里能不能过另说,但这种写法我不太喜欢,因为核心逻辑基本没了,像是把题交给库函数处理。

上面这段代码里,cleanBlank() 只干一件事:遇到单词就写进去,遇到空格先记一下,等下一个字符真是单词时,再补一个空格。

这样可以避开两个坑:

"  hello"
"hello   world"

第一个不会在开头补空格,第二个不会在中间补多个空格。

后面的翻转就没什么玄学了。

先整体翻:

reverse(cleaned, 0, cleaned.length - 1);

再扫描空格,找到一个单词边界就翻一次:

if (right == cleaned.length || cleaned[right] == ' ') {
    reverse(cleaned, left, right - 1);
    left = right + 1;
}

right == cleaned.length 这个判断别漏。最后一个单词后面没有空格,不加这个条件,最后一个单词就没人处理。

这题看着是字符串题,其实考的是边界处理。空字符串、全空格、多个连续空格、最后一个单词,这几个 case 跑一遍,代码基本就稳了。