现在的java后端已经没有大专学历了

文摘   2024-12-25 12:01   陕西  
最近在朋友圈和技术圈看到一个话题,真是让我感慨万千:现在的Java后端开发,真的是没有大专学历的位置了吗?


看到评论区有人说“外包都开始要求统招全日制本科了”


我记得刚开始进入后端开发时,大家对学历的要求并不那么严格。

那些外包公司,甚至有不少小公司,都更看重的是你的技术能力。只要能写出高质量的代码,问题能解决得干脆利索,学历什么的根本不重要。我的一位大专同学,技术出色,年年升职,根本没受到学历的困扰。

更糟糕的是,一些运维岗位的要求也变得很严格,“统招大专+成人本科都没人要了”这一说法,听得我都有些心虚。照这样发展下去,难道我们这些没有“本”证的程序员,真的就被“学历”挡在门外了吗?


不过,我还是相信一句话:最终决定你职业生涯的,永远是你的能力。如果你技术够硬,根本不怕什么学历限制,继续提升自己的能力,机会总会到来的!

算法题:奇怪的打印机

今天我们来聊聊一道比较有趣的算法题——奇怪的打印机

题目是这样的:给定一个字符串 s,打印机每次只能打印一个字符,并且打印机能够不断重复打印某个字符,直到用户选择停止。这就有点类似于“重复字符”的问题,但关键在于如何将这个“重复”的过程高效地处理。

这题的目标是找到打印出目标字符串 s 最少需要多少次打印。

举个例子,假设 s = "aaabbb",我们可以通过三次打印分别打印出:a, b,最后一次是 ab 连续打印,这样最少的打印次数就是 2 次。

一开始我看到这个题,第一反应是用递归做,结果发现不行。因为递归会把问题拆得太细,导致冗余计算,而且计算量指数级增长,想要优化算法就得好好动动脑筋了。

思路解析

首先要明确一点,这个问题可以看成是一个“区间合并”的问题。为什么这么说呢?我们可以根据相邻字符的重复性来分割问题。比如在 aaabbb 这个例子中,aaabbb 是两个区间,而我们可以把它们分别处理。

动态规划解法

我的思路是用 动态规划 来解这个问题。为什么呢?因为我们可以从较小的子问题开始逐步求解。

我们设定一个二维数组 dp[i][j],表示从第 i 个字符到第 j 个字符的最小打印次数。初始化时,单个字符的打印次数就是 1(因为一个字符只需要打印一次)。

接下来,我们需要填充这个 dp 数组。对于每一个区间 [i, j],我们需要看看怎么从小区间合并成大区间。

具体步骤如下:

  1. 对于每个区间 [i, j],先假设每个字符都独立打印。这样,最坏情况下,打印次数就是 dp[i][j] = j - i + 1
  2. 然后,我们检查区间内的重复字符。假设区间 s[i] == s[k],那么区间 [i, j] 的最小打印次数可以通过将 [i, k][k+1, j] 合并来得到。

代码实现

下面是我写的代码,使用了动态规划的思路:

public class StrangePrinter {

    public int strangePrinter(String s) {
        int n = s.length();
        // dp[i][j]表示从i到j最少的打印次数
        int[][] dp = new int[n][n];

        // 初始化:单个字符的区间
        for (int i = 0; i < n; i++) {
            dp[i][i] = 1;
        }

        // 动态规划:计算从i到j的最少打印次数
        for (int len = 2; len <= n; len++) {  // len是子区间的长度
            for (int i = 0; i <= n - len; i++) {
                int j = i + len - 1;
                dp[i][j] = dp[i][j - 1] + 1;  // 默认每个字符都独立打印
                for (int k = i; k < j; k++) {
                    // 如果s[k] == s[j],我们可以合并
                    if (s[k] == s[j]) {
                        dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k + 1][j] - 1);
                    } else {
                        dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k + 1][j]);
                    }
                }
            }
        }

        return dp[0][n - 1];
    }

    public static void main(String[] args) {
        StrangePrinter printer = new StrangePrinter();
        System.out.println(printer.strangePrinter("aaabbb")); // 输出2
        System.out.println(printer.strangePrinter("abcabc")); // 输出3
    }
}

这段代码是一个标准的动态规划解法,时间复杂度大约是 O(n^3),看起来有点高,但对于大多数常见的字符串长度来说,这个时间复杂度应该能接受。

优化

当然,如果我们想要更高效一点,可以通过记忆化搜索来减少一些冗余计算。但从目前的动态规划实现来看,已经算是一个较为合适的解法了。

总结来说,编程不仅仅是完成任务,更是通过不断优化,提升解决问题的效率和质量。就像我们在这道题中不断精细化每一步一样,在工作中,程序员的价值也往往体现在“看似不起眼但却非常高效”的优化中。

-END-


ok,今天先说到这,老规矩,给大家分享一份不错的副业资料,感兴趣的同学找我领取。

以上,就是今天的分享了,看完文章记得右下角给何老师点赞,也欢迎在评论区写下你的留言

程序员老鬼
10年+老程序员,专注于AI知识普及,已打造多门AI课程,本号主要分享国内AI工具、AI绘画提示词、Chat教程、AI换脸、Chat中文指令、Sora教程等,帮助读者解决AI工具使用疑难问题。
 最新文章