Java面向对象进阶:类名接口参数、内部类与常用API实战解析
说实话Java基础阶段学到第12天难度是突然往上跳了一截的。这天要啃的东西很杂但每个又很重要类名、抽象类名、接口名作为形参和返回值内部类那几种绕来绕去的写法Math、System、toString()、Arrays这些常用API再加上经典的冒泡排序。很多人在这一天会开始怀疑自己是不是不适合写代码因为知识密度实在太大。这篇文章是我把当天内容重新整理、消化后的学习笔记适合正在学Java面向对象、准备把“多态”往方法层面打通的人也适合想快速复习这些零散知识点的初学者。1. 类名、抽象类名、接口名作为形参和返回值把“多态”彻底吃透1.1 类名作为形参和返回值传的是对象引用不是类本身先说一个最原始的问题方法参数和返回值到底能不能写一个“类名”当然能。但你传入的、返回的永远是这个类创建出来的对象而不是这个类的字节码文件本身。这里的“类名”只是参数类型、返回类型真正流动的是对象的引用。Java中的参数传递只有一种规则值传递。基础类型传的是值的副本引用类型传的是引用地址的副本。看这段代码class Dog { String name; void setName(String name) { this.name name; } } public class Test { public void changeName(Dog dog) { dog.setName(旺财); } public Dog createDog() { Dog dog new Dog(); dog.setName(来福); return dog; } }调用changeName(dog)时方法里的dog和外面的dog指向堆中同一个对象所以方法内部改了name外面的对象也会变。但如果方法内部写的是dog new Dog()那只是把方法里的引用指向了新对象外面的引用还是指向原来的对象两码事。这个细节面试经常考理解之后很多“为什么方法里改了对象外面变了”的问题就不用死记了。返回值用类名也是同理createDog()返回的是Dog对象。要注意的是如果方法返回null调用方不做判空就直接调用对象方法马上就是空指针异常。1.2 抽象类作为形参和返回值给代码留扩展口抽象类不能new那抽象类作为参数到底能接什么答案是该抽象类的任意子类对象。这是多态最常见的体现之一。写一个支付流程模拟abstract class Pay { public abstract void pay(double money); } class PayByCard extends Pay { Override public void pay(double money) { System.out.println(卡支付 money); } } class PayByCash extends Pay { Override public void pay(double money) { System.out.println(现金支付 money); } }此时定义一个方法public void doPay(Pay pay, double money) { pay.pay(money); }调用的时候可以传new PayByCard()也可以传new PayByCash()。以后再加新的支付方式比如PayByCodedoPay方法一行都不用改。如果参数写死成某个具体子类每加一个支付方式就要重载一次方法代码会越来越臃肿。返回值也是一样。比如一个工厂方法public Pay createPay(int type) { if (type 1) { return new PayByCard(); } return new PayByCash(); }返回类型写成抽象类调用方拿到的是Pay类型的引用。这样做的代价是你通过这个引用只能调用抽象类中定义的方法。如果PayByCard自己有特殊方法比如queryCardBalance()直接pay.getCardBalance()编译都过不了必须先向下转型并且转型前最好用instanceof判断一下。1.3 接口作为形参和返回值比抽象类更灵活的设计契约接口比抽象类更抽象它只定义“能干什么”不关心“怎么干”。把刚才的例子改成接口interface IPay { void pay(double money); }参数写IPay pay就能接收任意实现类对象。接口可以有多个实现类而一个类也只能实现多个接口所以接口参数的“接纳范围”比抽象类更大。日常开发里方法参数和返回值最推荐写成接口这就是常说的“面向接口编程”。为什么推荐接口举个例子。一个数据保存功能interface IDataSaver { void save(String data); } class FileSaver implements IDataSaver { public void save(String data) { // 存文件 } } class DBSaver implements IDataSaver { public void save(String data) { // 存数据库 } }业务方法只需要依赖IDataSaver具体传入哪个Saver完全由调用方决定。以后要换存储方案业务代码不用动只要换个实现类或者动态传入。这种解耦能力在框架源码里到处都是比如各种监听器、回调接口、配置处理器。还有一点要注意接口没有构造方法不能new IPay()接口名作为返回值返回的必须是实现类的对象否则编译直接报错。1.4 三类参数/返回值对比一张表理清使用边界类型形参/返回值实际接收什么编译期能调用哪些方法典型场景具体类名该类对象及其子类对象具体类中定义的方法直接处理明确类型的对象抽象类名任意子类对象抽象类中定义的方法模板方法、公共流程封装接口名任意实现类对象接口中声明的方法策略模式、回调、系统解耦写到这里你会发现三者的本质是一件事参数或返回值声明成父类型实际塞进去的是子类型对象。父类型可以是具体类、抽象类、接口区别只是“约束范围”和“可调用方法”的宽窄。把这一点想明白面向对象才算真正往前迈了一步。2. 内部类Java的“套娃”玩法四种形态一次讲清2.1 成员内部类定义在类里的普通成员成员内部类就像外部类的一个成员变量位置在类内部、方法外面。它可以有private、public、protected修饰符可以访问外部类的所有成员包括私有成员因为内部类默认持有一个外部类对象的引用。创建方式比较特别class Outer { private int x 10; class Inner { public void show() { System.out.println(x); } } } Outer outer new Outer(); Outer.Inner inner outer.new Inner(); inner.show();看到outer.new Inner()这种语法不要慌意思就是“用outer这个对象去创建一个属于它的内部类对象”。成员内部类不能像普通类一样直接new Outer.Inner()必须先有外部类对象原因就是它要拿到外部类引用。一个很容易被忽略的面试细节如果外部类和内部类有同名字段在内部类中访问外部类字段要写成Outer.this.字段名。比如class Outer { int x 10; class Inner { int x 20; void show() { System.out.println(x); // 20 System.out.println(Outer.this.x); // 10 } } }这个语法在开发中不常见但理解了就知道内部类确实持有外部类的this引用。有没有坑有。因为内部类持有外部类引用如果内部类对象生命周期长而外部类对象不再被使用外部类就可能一直无法被垃圾回收。在一些GUI程序或者Android开发里这种写法容易导致内存泄漏所以现在大型项目里成员内部类用得并不算多。2.2 局部内部类方法里的临时类局部内部类定义在方法或者代码块里面作用域跟局部变量一样只能在所在方法内创建和使用。它不能加public、private这些修饰符因为对方法外部来说它根本不存在。这种类什么时候用当你发现方法内部的一段逻辑需要一个“类”来组织但这个方法外部永远用不到这个类就可以写局部内部类。不过实际开发中局部内部类经常被匿名内部类替代所以它更多是学习语法用。局部内部类最需要记住的坑是它访问方法里的局部变量时那个变量必须是final或者“实际上没被修改过”effectively final。为什么因为局部变量在栈帧里方法执行完就销毁了但局部内部类对象可能还在堆里存活Java为了保证它还能读到变量会把局部变量复制一份到内部类对象里。既然复制了就必须保证原变量不能变否则两边数据就对不上了。public void test() { int num 100; // 这个num之后不能再被修改 class Inner { public void print() { System.out.println(num); } } new Inner().print(); }如果你在num后面再写num 200编译直接报错。这个规则对匿名内部类同样适用。2.3 匿名内部类一个“用完即走”的子类对象匿名内部类最实用也是最常见的一种。它是“定义类创建对象”一起完成的写法没有类名。语法长这样new 父类/接口(参数) { // 类体 };最常见的场景是启动线程Thread t new Thread(new Runnable() { Override public void run() { System.out.println(线程执行了); } }); t.start();这里的new Runnable() {...}并不是在实例化接口而是在创建Runnable的一个匿名实现类对象。编译器会帮我们生成一个类似Outer$1.class的类文件。匿名内部类有四个特点需要记住只能创建一次对象没有名字无法再new第二次。如果是接口必须实现接口里所有抽象方法。如果是抽象类必须实现所有抽象方法。可以访问外部类的成员但访问局部变量时必须满足final或effectively final。在大多数JDK版本里匿名内部类中不能定义静态成员。匿名内部类是回调、监听器、事件处理的首选因为代码紧凑。后来Java 8推出Lambda表达式如果接口只有一个抽象方法可以直接用() - {}替代匿名内部类代码更简洁。但匿名内部类还能用于继承普通类、抽象类这点Lambda取代不了。2.4 静态内部类不依赖外部类实例的独立嵌套类静态内部类用static修饰它不会持有外部类对象的引用。创建方式也比成员内部类简单class Outer { static class StaticInner { public void say() { System.out.println(静态内部类); } } } Outer.StaticInner inner new Outer.StaticInner();不需要outer.new直接new Outer.StaticInner()。因为它是静态的所以只能访问外部类的静态成员不能访问外部类的实例成员。静态内部类在实际项目里非常有用。典型场景是数据模型中的嵌套结构比如一个响应结果类里再定义BaseResult和Data结构。Builder设计模式里也经常用静态内部类当作Builder。因为它是“静态”的不依赖外部类实例所以不会造成外部类无法回收的问题这一点比成员内部类更安全。2.5 四种内部类怎么选放在一起看更清楚内部类类型是否持有外部类this创建方式能访问外部类什么常见用途成员内部类是outer.new Inner()所有成员和外部类强相关、需要频繁访问私有属性的组件局部内部类是在所在方法内new所有成员 effectively final局部变量方法内需要复杂类型时匿名内部类是直接在new时定义所有成员 effectively final局部变量一次性回调、简化代码静态内部类否new Outer.StaticInner()只能访问静态成员Builder、嵌套数据模型从使用频率上看匿名内部类和静态内部类最高成员内部类次之局部内部类最低。学习阶段每个都要写得出来但真正写项目时优先考虑静态内部类和匿名内部类。3. 常用API一次摸清Math、System、toString、Arrays3.1 Math类数学计算别自己造轮子Math类是一个工具类构造方法是私有的所有方法都是静态的直接用Math.方法名()调用就行。常用方法列一下Math.abs(int a)取绝对值。但要小心Math.abs(Integer.MIN_VALUE)返回的还是Integer.MIN_VALUE因为Integer.MIN_VALUE的绝对值超出了int范围。Math.ceil(double a)向上取整返回double。Math.ceil(3.2)结果是4.0。Math.floor(double a)向下取整返回double。Math.floor(3.8)结果是3.0。Math.round(double a)四舍五入返回long。Math.round(3.5)结果是4。Math.max/min返回两个数里较大/较小的那个。Math.pow(double a, double b)a的b次方返回double。比如Math.pow(2, 10)是1024.0。Math.random()返回0.0 x 1.0的随机double。想要1到100的随机整数可以写(int)(Math.random() * 100) 1注意先乘后取整。Math.round有个非常经典的坑Math.round(-1.5)的结果不是-2而是-1。原因要看源码Math.round(a)等价于Math.floor(a 0.5)。-1.5 0.5 -1.0再向下取整还是-1。如果写成Math.round(-1.6)-1.6 0.5 -1.1向下取整就是-2。这个细节很多题会考记住思路就不容易错。3.2 System类与运行时环境打交道的入口System类也是一个静态工具类最常用的几个方法System.currentTimeMillis()返回当前时间距离1970年1月1日0时0分0秒的毫秒数。常用来测代码耗时long start System.currentTimeMillis(); for (int i 0; i 1000000; i) { // 模拟耗时操作 } long end System.currentTimeMillis(); System.out.println(耗时(ms) (end - start));注意currentTimeMillis()返回的是绝对时间戳不是精确计时器受系统时间调整影响。如果需要更精确的纳秒级计时可以用System.nanoTime()。System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)数组复制。Arrays.copyOf底层就是用它实现的。参数从左到右是源数组、源数组起始位置、目标数组、目标数组起始位置、复制长度。使用前要确保目标数组长度够否则会抛ArrayIndexOutOfBoundsException。System.gc()请求JVM执行垃圾回收。注意只是“请求”JVM不一定立刻响应正式代码里不要依赖它。System.exit(int status)终止当前JVM进程0表示正常退出非0表示异常终止。这个方法能不用就不用尤其在企业级应用里随手exit会把整个服务停掉。3.3 toString()为什么打印对象不是想要的内容所有类都继承自ObjectObject类里有一个toString()方法默认实现返回的是类名十六进制哈希值比如com.demo.Dog1b6d3586。这就是为什么你直接System.out.println(对象)时输出的是一串看不懂的地址。其实System.out.println在打印对象时会自动调用这个对象的toString()方法。所以只要重写toString()打印出来的内容就能变成你想要的样子class Dog { private String name; Override public String toString() { return Dog{name name }; } }IDE一般都有自动生成toString()的功能自己不用手敲。重写时保持简洁别在toString()里写复杂业务逻辑因为字符串拼接、日志框架、异常信息都可能悄悄调用它逻辑太复杂会影响性能。数组的toString有点特殊。int[] arr {1,2,3}直接System.out.println(arr)会输出[I1b6d3586这种不会输出元素。因为数组没有真正重写toString()用的还是Object里的那套。但char[]例外System.out.println(charArr)会直接打印字符序列因为PrintStream有重载的print(char[])方法。这个如果不注意调试时遇到字符数组“能打印、其他数组不能打印”的现象会一脸懵。3.4 Arrays类数组操作的标准答案java.util.Arrays是专门操作数组的工具类全都封装成了静态方法。Arrays.toString(int[] arr)把数组内容转成字符串输出[1, 2, 3]这样。这是调试利器。Arrays.sort(int[] arr)原地升序排序。注意是“原地”排序后会修改原数组。底层对基本类型用的是双轴快排对对象数组用的是归并排序或者TimSort。Arrays.binarySearch(int[] arr, int key)二分查找返回找到的下标。如果没找到返回的不是-1而是-(插入点) - 1。比如在{1, 3, 5}里查找2插入点是1返回值就是-2。使用前提是数组必须先排序否则结果不可预期。Arrays.copyOf(int[] arr, int newLength)复制数组并指定新长度。扩容时多出来的位置补默认值缩容时多余的直接丢弃。底层用System.arraycopy实现。Arrays.copyOfRange(int[] arr, int from, int to)复制范围包左不包右。Arrays.fill(int[] arr, int val)把数组的所有位置都填成同一个值。Arrays.equals(int[] a, int[] b)比较两个数组的“内容”是否相等而不是比较引用。很多人喜欢写arr1 arr2来比较数组这比较的是两个引用是不是指向同一个对象即使内容完全一样也会返回false。还要注意一个坑Arrays.sort(int[], Comparator)是不存在的。因为Comparator是泛型接口需要传对象而int是基本类型。如果想让int[]降序排列要么换成Integer[]要么自己写排序要么先升序再反转。初学者很容易在这里编译报错。4. 冒泡排序把每个最大值“冒”到末尾4.1 核心思路与手动推演冒泡排序是排序算法里最直观的一个。思路就一句话从头开始相邻两个数两两比较如果左边比右边大就交换位置。每一轮比较结束后当前参与比较的范围里最大的那个数会“冒泡”到范围末尾下一轮就不再管它。以数组[5, 1, 4, 2, 8]为例手动走一遍第一轮比较5和15 1交换数组变成[1, 5, 4, 2, 8]比较5和45 4交换数组变成[1, 4, 5, 2, 8]比较5和25 2交换数组变成[1, 4, 2, 5, 8]比较5和85 8不交换数组保持[1, 4, 2, 5, 8]第一轮结束后8已经在最后一位。第二轮只需要处理[1, 4, 2, 5]这四个数比较3次结束之后5到倒数第二位。第三轮处理[1, 4, 2]比较2次。第四轮处理[1, 2]比较1次。总共比较432110次正好是n(n-1)/2因为n5所以5*4/210。4.2 标准代码实现与边界解释手写标准冒泡排序public static void bubbleSort(int[] arr) { if (arr null || arr.length 2) { return; } for (int i 0; i arr.length - 1; i) { for (int j 0; j arr.length - 1 - i; j) { if (arr[j] arr[j 1]) { int temp arr[j]; arr[j] arr[j 1]; arr[j 1] temp; } } } }为什么外层循环是i arr.length - 1因为当只剩最后一个元素时它天然有序不需要再比较。为什么内层是j arr.length - 1 - i因为每轮结束后末尾已经有i个元素排好序不需要再碰它们同时循环里要访问arr[j 1]所以j最大只能到倒数第二位的下标也就是length - 2写成 length - 1刚好。外层循环从i 0开始第一轮结束时最大值到末尾i 1第二轮结束前二大值到倒数第二位以此类推。这段代码必须要能默写不只是为了面试而是因为它能锻炼“循环边界”的敏感度写错一点就是越界异常。4.3 稳定性、时间复杂度与优化冒泡排序是稳定排序前提是交换条件严格使用相等时不交换相同元素的相对顺序不会改变。如果你写成相等的两个元素也会交换排序结果虽然一样但稳定性就被破坏了。在只比较int时看不出来但如果排序的是对象比如按年龄排序学生对象两个学生年龄相同稳定排序能保持他们原来的先后顺序不稳定排序可能颠倒。时间复杂度分情况最好情况数组已经有序。优化前仍要跑完所有轮复杂度是O(n^2)优化后只需要一检测轮复杂度降到O(n)。平均和最坏情况O(n^2)。空间复杂度O(1)因为只用了一个临时变量没有额外数组。优化版本加一个标志位记录当前轮是否发生过交换public static void bubbleSortOptimized(int[] arr) { if (arr null || arr.length 2) { return; } for (int i 0; i arr.length - 1; i) { boolean swapped false; for (int j 0; j arr.length - 1 - i; j) { if (arr[j] arr[j 1]) { int temp arr[j]; arr[j] arr[j 1]; arr[j 1] temp; swapped true; } } if (!swapped) { break; } } }这个优化对“大部分已经有序”的数据非常友好。比如[1, 2, 3, 4, 5, 6, 7]第一轮内层跑完发现一次交换都没有直接break只需要比较6次效率极高。4.4 手写冒泡最常见的三类错误第一类内层循环边界写成j arr.length - i当j到length - i - 1时arr[j 1]就越界了抛ArrayIndexOutOfBoundsException。记住一个口诀因为比较的是j和j1所以j最多到倒数第二位也就是length - 2。第二类外层循环写成i arr.length虽然不会越界但会多跑一轮无用循环。最后只剩一个元素时根本不需要再比较。第三类没有意识到Arrays.sort和冒泡排序都是“原地排序”数组在排序方法内部被修改了。如果调用方后面还要用原始顺序必须先用Arrays.copyOf复制一份再排序。5. 学习中的常见问题与排查技巧实录5.1 方法参数写接口子类特有方法调不出来场景方法参数是接口类型但实现类里有一个额外方法在方法内部直接调用编译报错。原因前面说过编译期看的是左边的类型接口类型只能调用接口里的方法。解决办法if (obj instanceof Circle c) { c.setRadius(10); }从JDK 16开始instanceof可以用模式匹配直接拿到变量不需要再强转。不过从设计角度看如果调用方频繁需要向下转型说明接口定义得太薄该把公共方法提到接口里或者拆分成细粒度接口。5.2 Arrays.sort 不能直接给 int[] 传 Comparator 降序“为什么我给int[]传Comparator会报错”因为Comparator只适用于对象类型int是基本类型不满足泛型约束。想用Arrays.sort降序时方案一用Integer[]然后Arrays.sort(arr, (a, b) - b - a)。方案二先升序Arrays.sort(arr)再手动反转。方案三自己写降序冒泡。这个坑的本质是理解基本类型和包装类型在泛型中的区别。int[]在泛型方法里就是个整体对象没法拆成一个个Integer元素去套Comparator。5.3 打印数组到底用什么一维数组用Arrays.toString()二维数组用Arrays.deepToString()。如果用了Arrays.toString()打印二维数组看到的是一堆[Ixxx地址不是具体元素。调试时直接System.out.println(Arrays.deepToString(matrix));一眼就能看清所有行和列。5.4 内部类编译后的class文件疑问编译包含内部类的外部类后目录里会出现Outer$Inner.class这样的文件匿名内部类会生成Outer$1.class、Outer$2.class这种带数字的文件。看到这个不要觉得奇怪这是Java编译器的正常产物。如果你用命令行javac编译并手动运行必须把这些class文件都带上漏了就会ClassNotFoundException。IDE开发时这些细节被隐藏了但底层逻辑要清楚。5.5 匿名内部类里改局部变量为什么编译失败因为局部变量必须是final或effectively final。你可以在匿名内部类里“读取”它但不能再回头“修改”它。如果非要改常见做法是定义一个长度为1的数组用数组下标来绕。但更推荐的做法是把这个值改成外部类的成员变量或者从设计层面换一种写法别为了省事钻语言限制的空子。5.6 冒泡排序结果不对怎么定位第一步检查输出的是不是原数组。因为排序是原地的如果你先打印原数组再排序打印的是排序后的结果容易误判。第二步在每轮内层交换的位置加一行日志if (arr[j] arr[j 1]) { int temp arr[j]; arr[j] arr[j 1]; arr[j 1] temp; System.out.println(交换下标 j 和 (j 1) Arrays.toString(arr)); }这样能看到每个交换动作边界问题一目了然。第三步写一个验证方法static boolean isSorted(int[] arr) { for (int i 0; i arr.length - 1; i) { if (arr[i] arr[i 1]) { return false; } } return true; }排序结束后调用一下返回false就说明还有元素没排好。这个验证方法以后自己写排序时也能用。最后分享一个小习惯。学完这一天的内容后我建议做一个小练习设计一个精简版的学生成绩处理程序Service层方法的参数和返回值都用接口类型内部用匿名内部类或Lambda处理排序规则最后对成绩数组手写一次冒泡排序再用Arrays.sort对比结果。这个练习不复杂但能把类名/接口作为参数返回值、内部类、常用API、冒泡排序这些散点全部串起来。我当时做完之后很多“似懂非懂”的感觉一下消失了。如果你也卡在这一天强烈建议亲手码一遍比刷十道题都管用。

相关新闻

目标检测五大架构实战选型指南:从R-CNN到YOLO的工程落地路径

目标检测五大架构实战选型指南:从R-CNN到YOLO的工程落地路径

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 1:24:00 阅读更多 →
STM32移植FAT文件系统到SD卡:底层驱动与接口适配深入解析

STM32移植FAT文件系统到SD卡:底层驱动与接口适配深入解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 1:24:00 阅读更多 →
SpringBoot+MybatisPlus多模块系统构建实战

SpringBoot+MybatisPlus多模块系统构建实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 1:24:00 阅读更多 →

最新新闻

Natron ErodeSmooth 节点完全指南:归一化功率加权腐蚀/膨胀滤镜的参数解析与源码级解读

Natron ErodeSmooth 节点完全指南:归一化功率加权腐蚀/膨胀滤镜的参数解析与源码级解读

音视频视频处理图形学桌面应用 【免费下载链接】Natron Open-source video compositing software. Node-graph based. Similar in functionalities to Adobe After Effects and Nuke by The Foundry. 项目地址: https://gitcode.com/gh_mirrors/na/Natron 点击查看 …

2026/10/15 3:32:41 阅读更多 →
GreaterWMS 移动端构建实战:基于 Quasar CLI 与 Cordova 的 Android 打包安装全流程

GreaterWMS 移动端构建实战:基于 Quasar CLI 与 Cordova 的 Android 打包安装全流程

后端前端企业应用 【免费下载链接】GreaterWMS This Inventory management system is the currently Ford Asia Pacific after-sales logistics warehousing supply chain process . After I leave Ford , I start this project . You can share your vacant warehouse space, …

2026/10/15 3:32:41 阅读更多 →
从Apollo-11代号项目到可复现工程:逆向拆解与改造指南

从Apollo-11代号项目到可复现工程:逆向拆解与改造指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 3:32:41 阅读更多 →
rospack depends1 报错排查:ROS依赖查询与环境变量配置实战

rospack depends1 报错排查:ROS依赖查询与环境变量配置实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 3:32:41 阅读更多 →
Vue2多页面应用模板:从vue.config.js到webpack配置的完整实践

Vue2多页面应用模板:从vue.config.js到webpack配置的完整实践

简介:Vue 2.0多页面应用模板面向需要同时维护多个独立页面的前端开发场景,旨在解决传统单页应用在官网、专题页等多入口项目中重复搭建构建流程、难以统一工程化配置的问题。资源包共32个文件,压缩后仅31KB,包含15个JavaScript脚本…

2026/10/15 3:32:41 阅读更多 →
NC65销售订单批量导入实战:从数据清洗到SQL脚本全攻略

NC65销售订单批量导入实战:从数据清洗到SQL脚本全攻略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 3:31:40 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →