☰
Beboss 前端测试题全解析:PHP 无限层级商品分组、jQuery 轨迹采集插件与 XSLT 服务端转换
2026/10/9 2:38:06 网站建设 项目流程
  • 教程

【免费下载链接】ru-test-assignments

Тестовые задания для самостоятельного выполнения от разных it компаний

项目地址:https://gitcode.com/gh_mirrors/ru/ru-test-assignments
点击查看免费下载

本文以 Beboss(beboss.ru)前端/全栈岗位的完整测试题集为主线,逐题拆解 5 个任务的技术要求、数据模型与可实现方案:核心题是用 PHP + MySQL 实现不限制层数的嵌套商品分组展示(含子树商品计数与递归下钻),附加题覆盖 jQuery 鼠标轨迹采集插件、Yii 2.0 三页面站点,以及基于 XsltProcessor/DomDocument 的 XML→HTML 服务端转换。读完本文,你可以掌握邻接表建树、子树聚合计数、jQuery 插件化封装、XSLT 递归模板与分组索引等一类可直接复用的实战技巧。

测试题全景:5 个任务的定位与仓库文件布局

这份测试题集存放在仓库的 frontend/beboss/beboss-test-assignments.md,配套数据文件位于 frontend/beboss/beboss-test-assignments/ 目录,参考效果图在 frontend/beboss/img/。题目结构如下:

任务技术主题类型配套数据文件
任务一PHP + MySQL 无限层级商品分组必做(核心题)test-base.sql
任务二jQuery 鼠标轨迹采集插件必做无(自建数据)
任务三Yii 2.0 多页面站点可选无
任务四XsltProcessor + DomDocument 转换 users.xml可选users.xml
任务五XSLT 转换 cities.xml 生成城市字母索引可选cities.xml

任务一与任务二为必做项,任务三至五为加分项。整体考察方向很清晰:递归/树形数据处理、纯 PHP 与 SQL 功底、jQuery 插件设计、Yii 标准用法,以及 XSLT 服务端渲染。仓库中三个数据文件(SQL 转储、两份 XML)与三张任务一的参考截图,恰好提供了做题所需的全部输入数据与预期输出样例。

任务一:PHP + MySQL 无限层级商品分组(核心题)

题目设定了一个已有的电商场景:现有代码能输出"分组列表"和"分组内商品",需要在不破坏既有逻辑的前提下为它加上"嵌套分组"能力。这是一道典型的递归 + 邻接表改造题,评估重点明确写在题面里:SQL 查询、实现嵌套分组逻辑的 PHP 代码,以及实现嵌套列表的 HTML 代码。

数据模型:groups 与 products 两张表

仓库中的 test-base.sql 是完整的 MySQL 转储,表结构如下:

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; CREATE TABLE IF NOT EXISTS `groups` ( `id` int(11) NOT NULL AUTO_INCREMENT, `id_parent` int(11) NOT NULL, `name` varchar(100) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=11 ; CREATE TABLE IF NOT EXISTS `products` ( `id` int(11) NOT NULL AUTO_INCREMENT, `id_group` int(11) NOT NULL DEFAULT '0', `name` varchar(250) NOT NULL, PRIMARY KEY (`id`), KEY `id_group` (`id_group`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=18 ;

关键点:

  • groups.id_parent = 0表示一级分组(根节点),其余值指向父分组 id,即标准的**邻接表(adjacency list)**模型;
  • products.id_group关联到分组 id,默认值 0(未归类商品);
  • products表在id_group上建有普通索引KEY id_group,便于按分组批量取商品;
  • 两组表均为 MyISAM 引擎、utf8 字符集。

转储中预置了 10 个分组、17 个商品,构成一个三层的真实分类树(家电行业常见分类),层级关系为:

Телевизоры 电视机 (1) ├── ЖК телевизоры 液晶电视 (3) │ ├── Диагональю до 45 дюймов 45 英寸以下 (5) │ └── Диагональю более 40 дюймов 40 英寸以上 (6) └── Плазменные телевизоры 等离子电视 (4) ├── Диагональю до 45 дюймов (7) └── Диагональю более 40 дюймов (8) Мультимедиа 多媒体 (2) ├── DVD-плееры (9) └── Blu-Ray плееры (10)

例如商品Телевизор Erisson 1435直接挂在分组 1 下,Телевизор-ЖК Samsung LE32D403挂在分组 3 下,DVD-плеер BBK DVP 753HD挂在分组 9 下——每个分组既可能有直接商品,也可能有子分组,这正是"总数 = 自身商品数 + 全部后代分组商品数"的由来。

需求拆解:六条约束逐条解读

  1. 首屏行为:输出一级分组(id_parent=0)的<ul>列表,每个分组名是链接,指向本脚本自身并携带 GET 参数group=<分组id>;分组名旁显示该分组"子树商品总数";未选择任何分组时,同时输出全量商品列表。
  2. 下钻行为:点击一级分组后,除保留一级分组列表外,还要展开所选分组的全部直接子分组(子分组名同样是链接并带数量),并输出属于该分组及其所有后代分组的商品列表。
  3. 层级不限:分组嵌套层数无上限,禁止写死深度(如只支持两三层)。
  4. 技术栈受限:仅 php、mysql、html(xslt 可选);除模板渲染外不得使用任何库或框架。
  5. 向后兼容:可新增字段(需提供回填数据的 SQL 或说明回填逻辑),但禁止修改字段类型、删除字段、改变既有逻辑。
  6. 不做美化:不要求任何特殊样式,评的是逻辑、SQL、PHP 与嵌套 HTML 的实现质量。

实现要点一:把邻接表一次性载入内存并建树

受第 4 条限制,方案应为纯 PHP + PDO。最稳妥的做法是两条 SQL 把全部数据读进内存,在 PHP 中建树,而不是在 SQL 里逐层递归(否则会有 N+1 次查询,且 MySQL 5.x 时代没有通用递归 CTE):

<?php $pdo = new PDO('mysql:host=localhost;dbname=beboss;charset=utf8', 'user', 'pass', [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); // 1. 一次性读取全部分组与商品 $groups = $pdo->query('SELECT id, id_parent, name FROM `groups` ORDER BY id') ->fetchAll(PDO::FETCH_ASSOC); $products = $pdo->query('SELECT id, id_group, name FROM products') ->fetchAll(PDO::FETCH_ASSOC); // 2. 邻接表 -> 内存树:children[父id] = [子分组…] $children = []; foreach ($groups as $g) { $children[$g['id_parent']][] = $g; } // 3. 商品按 id_group 归组 $byGroup = []; foreach ($products as $p) { $byGroup[$p['id_group']][] = $p; }

注意表名groups是 MySQL 的保留字风险项(旧版可用,新版本建议反引号包裹),转储中已经用反引号做了处理,PHP 侧拼 SQL 时也应保持一致。

实现要点二:递归统计子树商品总数

数量规则是"分组自身商品数 + 所有后代分组商品数之和",用一次深度优先递归即可求出所有分组的计数,避免每个分组单独查询:

function countSubtree(int $id, array &$children, array &$byGroup, array &$counts): int { $total = count($byGroup[$id] ?? []); foreach ($children[$id] ?? [] as $child) { $total += countSubtree($child['id'], $children, $byGroup, $counts); } $counts[$id] = $total; return $total; } $counts = []; foreach ($children[0] ?? [] as $root) { countSubtree($root['id'], $children, $byGroup, $counts); }

把该函数的结果与转储数据手工核对一遍,可验证逻辑正确性:

分组自身直接商品后代分组商品子树总数
Телевизоры (1)2(id 16、17)10(分组 3/4/5/6/7/8 内)12
Мультимедиа (2)1(id 4)4(分组 9、10 内)5
ЖК телевизоры (3)1(id 16)5(分组 5、6 内)6
Плазменные телевизоры (4)1(id 10)4(分组 7、8 内)5

这与参考效果图 task1-img-1.png 中"Телевизоры 12 / Мультимедиа 5"的标注完全一致。

实现要点三:嵌套 UL 渲染与沿选中路径下钻

渲染逻辑的关键是:一级分组永远显示;只有"被选中分组所在路径"上的节点才向下展开一层子分组。用"某分组是否位于选中分组的祖先链上"作为展开条件,即可实现任意深度的逐级下钻:

function isInSubtree(int $target, int $root, array &$children): bool { if ($target === $root) return true; foreach ($children[$root] ?? [] as $child) { if (isInSubtree($target, $child['id'], $children)) return true; } return false; } function renderGroups(int $parentId, int $selected, array &$children, array &$counts): string { $html = '<ul>'; foreach ($children[$parentId] ?? [] as $g) { $html .= '<li>' . '<a href="?group=' . (int)$g['id'] . '">' . htmlspecialchars($g['name']) . '</a>' . ' <span>(' . (int)$counts[$g['id']] . ')</span>'; // 只有选中分组所在路径才继续展开 if ($selected && isInSubtree($selected, $g['id'], $children)) { $html .= renderGroups($g['id'], $selected, $children, $counts); } $html .= '</li>'; } return $html . '</ul>'; } $selected = isset($_GET['group']) ? (int)$_GET['group'] : 0; echo renderGroups(0, $selected, $children, $counts);

要点说明:

  • 分组名必须用htmlspecialchars()转义(分类名是外部数据),数量括在括号中;
  • GET 参数名固定为group,链接指向本脚本自身(?group=N),与题面"调用这个脚本"的要求一致;
  • 该递归天然支持不限层数;数据量很大时可将isInSubtree预先计算为"祖先链集合"来避免重复遍历(此处演示版优先保证可读性)。

实现要点四:选中分组的子树商品查询

点击分组后要展示"该分组及其全部后代分组"的商品。做法是先收集子树全部分组 id,再构造一次WHERE id_group IN (...):

function collectIds(int $id, array &$children, array &$ids): void { $ids[] = $id; foreach ($children[$id] ?? [] as $child) { collectIds($child['id'], $children, $ids); } } if ($selected) { $ids = []; collectIds($selected, $children, $ids); $in = implode(',', array_map('intval', $ids)); $shown = $pdo->query("SELECT id, id_group, name FROM products WHERE id_group IN ($in)") ->fetchAll(PDO::FETCH_ASSOC); } else { $shown = $products; // 未选择分组:输出全部商品 }

商品输出同样用<ul>/<li>列表即可,无需额外样式。

参考效果:三阶段界面

题目给出了" эталонный результат"(参考结果)的三张截图,恰好对应上述三个交互阶段:

  • task1-img-1.png:未选择分组时,仅显示两个一级分组(Телевизоры 12、Мультимедиа 5),右侧列出全部 17 件商品;
  • task1-img-2.png:点击 Телевизоры 后,其下方展开两个二级分组(ЖК 6、Плазменные 5),右侧商品列表变为电视机子树的 12 件商品;
  • task1-img-3.png:继续点击 ЖК телевизоры,再展开两个三级分组(各 2 件与 3 件),右侧只显示液晶电视子树的 6 件商品。

三张图验证了两个关键行为:列表沿选中路径逐级展开,商品列表始终对应当前分组子树——与上述 PHP 递归逻辑的输出一一对应。

关于"允许新增字段"的延伸思考

题面第 5 条允许加字段,但必须附上回填脚本。常见的优化方向(作答时如使用需写清回填 SQL 或逻辑):

  • 加lft/rgt(嵌套集模型)或path(物化路径)字段,把"子树查询"从递归变成单条范围查询;
  • 加level字段缓存分组深度,便于直接渲染层级;
  • 为groups.id_parent建索引(转储中未建,仅id主键),加速父查子操作。

任何新增字段都必须用一条 UPDATE/递归脚本回填存量数据,例如物化路径可以逐层 UPDATE 拼接父路径。从仓库转储看,10 个分组规模下递归方案已完全够用,加字段属于对大规模数据的工程化演进。

任务二:jQuery 鼠标轨迹采集插件 trackCoords

第二题要求写一个 jQuery 插件:每 30ms 采集一次鼠标在页面上的位置与停留时间,再批量发送到服务器,数据为"坐标点 + 停留时长"的对象数组。服务器端不需要实现,发送目标通过参数给定。

插件 API 契约

配置项类型默认值含义
checkIntervalnumber(ms)30数据采集(采样)周期
sendIntervalnumber(ms)3000数据上报周期(3 秒一批)
urlstring—数据接收地址,必填

调用方式固定为 jQuery 对象方法:

$("div.container").trackCoords({url: '/save.php'});

即插件挂在$.fn上、作用于某个容器元素,鼠标坐标要换算为相对该容器的坐标(而非页面绝对坐标)。

参考实现:采样、聚合与批量上报

(function ($) { $.fn.trackCoords = function (options) { var settings = $.extend({ checkInterval: 30, // 采样周期(默认 30ms) sendInterval: 3000, // 上报周期(默认 3s) url: null // 接收地址(必填) }, options); return this.each(function () { var $box = $(this); var hold = {}; // 'x,y' -> 累计停留毫秒 var points = []; // 待上报: [{x, y, time}] var lastX = null, lastY = null, lastTs = null; // 定时采样:把"光标停留时长"累加到当前点 setInterval(function () { if (lastX !== null) { var now = Date.now(); var key = lastX + ',' + lastY; hold[key] = (hold[key] || 0) + (now - lastTs); lastTs = now; } }, settings.checkInterval); // 定时上报:整批 POST 到 url setInterval(function () { if (points.length === 0) return; var payload = points.slice(); points.length = 0; $.ajax({ url: settings.url, type: 'POST', data: JSON.stringify(payload), contentType: 'application/json' }); }, settings.sendInterval); // 移动事件:换算相对坐标,结算上一个点的停留时长 $box.on('mousemove', function (e) { var offset = $box.offset(); var x = e.pageX - offset.left; // 相对容器的坐标 var y = e.pageY - offset.top; if (lastX !== null && (x !== lastX || y !== lastY)) { var key = lastX + ',' + lastY; points.push({ x: lastX, y: lastY, time: (hold[key] || 0) + (Date.now() - lastTs) }); delete hold[key]; } lastX = x; lastY = y; lastTs = Date.now(); }); }); }; })(jQuery);

实现要点:

  • 相对坐标:e.pageX - $box.offset().left、e.pageY - $box.offset().top,与题面"坐标相对于该对象计算"一致;
  • 时间归属:在 mousemove 时结算上一个点的停留时长,空闲期由checkInterval定时器持续累加,避免"鼠标不动就没时间";
  • 批量上报:sendInterval定时把缓冲数组整体发出(POST + JSON),发出后清空缓冲;
  • 链式调用:return this.each(...)保持 jQuery 链式语义,符合"作为 jQuery 对象方法调用"的题面要求;
  • 改进空间:鼠标离开容器时(mouseleave)可做一次"最终 flush"把剩余点发出,避免数据滞留内存。

任务三(可选):Yii 2.0 三页面站点

可选任务三要求用Yii 2.0 标准方法搭一个三页面站点,考察 MVC 路由与表单/Ajax 交互。

页面与路由设计

路由页面内容
/主页用户列表
/request申请页表单:下拉选择接收用户 + 发送方联系方式 + 申请文本
/<alias>用户页按文本别名打开([a-zA-Z0-9]+,且别名不能是request),显示用户资料 + 无接收人选择的申请表单

在config/main.php的 urlManager 中配置美化路由与规则,注意把request作为保留字排在别名规则之前:

'urlManager' => [ 'enablePrettyUrl' => true, 'showScriptName' => false, 'rules' => [ 'request' => 'site/request', '<alias:[a-zA-Z0-9]+>' => 'user/view', '' => 'user/index', ], ],

关键实现:标准 Yii 动作 + Ajax 加载用户信息

控制器使用 Yii 标准查询与渲染方法:

public function actionIndex() { return $this->render('index', ['users' => User::find()->all()]); } public function actionRequest() { $model = new RequestForm(); if ($model->load(Yii::$app->request->post()) && $model->validate()) { // 保存申请、发送通知等(Yii 标准模型流程) } return $this->render('request', [ 'model' => $model, 'users' => User::find()->all(), ]); } public function actionView($alias) { $user = User::find()->where(['alias' => $alias])->one(); if ($user === null) { throw new NotFoundHttpException('用户不存在'); } return $this->render('view', ['user' => $user]); }

题面明确要求:在通用表单中选择接收用户后,需用 Ajax 拉取并展示该用户的信息。前端配合一个返回 JSON 的动作即可:

$('#request-recipient').change(function () { $.ajax({ url: '/user/info', data: { id: $(this).val() }, dataType: 'json', success: function (data) { $('#recipient-info').html( data.fname + ' ' + data.sname + ' <' + data.email + '>' ); } }); });

考察点在于:是否使用find()/where()/render()等标准 Yii API、路由规则中保留字处理是否得当、Ajax 交互是否符合题面"选择用户后加载其信息"的时序要求。

任务四(可选):XsltProcessor + DomDocument 转换 users.xml

任务四要求用 PHP 的XsltProcessor与DomDocument在服务器端把 users.xml 转换为 HTML,输出两部分内容:① 用户类型的树形结构;② 形如"Имя Фамилия | Привязанные категории: Категория1, Категория2"的用户列表。

输入 XML 结构分析

users.xml根节点为<root>,包含三类节点:

  • <usertypes>:14 个<usertype>,字段id、id_parent(0 表示根)、title。实际构成两棵子树——根类型"Специальные типы"(id=14,下挂 Арендатор/Риелтор/Собственник бизнеса/Инвестор/Девелопер/Бизнес брокер/Специалист по недвижимости/Специалист по оценке/Ипотечный брокер/Другой 共 10 个)和"Общие типы"(id=13,下挂 Пользователь/Администратор);
  • <userlinks>:12 条<link>绑定,字段id_user、id_usertype,例如用户 7126 同时绑定类型 3(Собственник бизнеса)与 4(Инвестор);
  • <users>:7 个<user>,字段id、fname(名)、sname(姓)。

因此示例输出中应能看到类似:Сидор Михайлов | Привязанные категории: Собственник бизнеса, Инвестор。

XSLT 实现要点:key 索引 + 模板递归

XSLT 1.0 的核心技巧是用<xsl:key>建立三类索引(按父 id、按类型 id、按用户 id),再用"根类型→子类型"的模板递归生成树,用 key 反查把用户绑定翻译成类型名:

<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" encoding="UTF-8" indent="yes"/> <xsl:key name="types-by-parent" match="usertype" use="id_parent"/> <xsl:key name="types-by-id" match="usertype" use="id"/> <xsl:key name="links-by-user" match="link" use="id_user"/> <xsl:template match="/root"> <html><body> <h1>Дерево типов пользователей</h1> <ul> <xsl:apply-templates select="usertypes/usertype[id_parent=0]" mode="tree"/> </ul> <h1>Пользователи</h1> <xsl:apply-templates select="users/user"/> </body></html> </xsl:template> <!-- 递归输出类型树:每个类型下若有子类型则继续嵌套 <ul> --> <xsl:template match="usertype" mode="tree"> <li> <xsl:value-of select="title"/> <xsl:if test="key('types-by-parent', id)"> <ul> <xsl:apply-templates select="key('types-by-parent', id)" mode="tree"/> </ul> </xsl:if> </li> </xsl:template> <!-- 用户列表:名字 + 绑定的全部类型(逗号分隔) --> <xsl:template match="user"> <p> <xsl:value-of select="fname"/> <xsl:text> </xsl:text> <xsl:value-of select="sname"/> <xsl:text> | Привязанные категории: </xsl:text> <xsl:for-each select="key('links-by-user', id)/id_usertype"> <xsl:value-of select="key('types-by-id', .)/title"/> <xsl:if test="position() != last()"><xsl:text>, </xsl:text></xsl:if> </xsl:for-each> </p> </xsl:template> </xsl:stylesheet>

PHP 侧加载与执行转换(语言限定为 PHP,且必须使用XsltProcessor+DomDocument):

$xml = new DomDocument(); $xml->load('users.xml'); $xsl = new DomDocument(); $xsl->load('users.xsl'); $proc = new XsltProcessor(); $proc->importStylesheet($xsl); echo $proc->transformToXml($xml); // 输出 HTML

transformToXml()返回转换后的 HTML 字符串,直接 echo 即可;若需保存文件可改用transformToURI()。考察点集中在:key 索引是否正确、类型树递归是否收敛(终止于无子类型节点)、多类型绑定是否正确拼接。

任务五(可选):cities.xml 城市字母索引

任务五用同样的 XSLT 技术把 cities.xml 转换成字母索引页,样式参照题目中给出的 Beboss 网站字母索引页面:每个城市按首字母分组,城市名是链接,href取该城市的name_latin。

输入数据

cities.xml共 37 个<node>,字段为id(城市 id)、id_region(区域 id)、name(俄文城市名)、name_latin(拉丁名)。例如Москва/msk、Санкт-Петербург/spb、Екатеринбург/ekb、Нижний Новгород/nn。转换后每个城市应形如<a href="msk">Москва</a>。

XSLT 实现要点:按首字母分组(Muenchian 法)+ 双重排序

XSLT 1.0 没有 group-by,通常用"按首字母建立 key + 取每组第一个节点"的 Muenchian 分组法:

<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" encoding="UTF-8"/> <xsl:key name="cities-by-letter" match="node" use="substring(name, 1, 1)"/> <xsl:template match="/root"> <html><body> <!-- 遍历"每个首字母只取一次"的代表节点 --> <xsl:for-each select="cities/node[generate-id() = generate-id(key('cities-by-letter', substring(name, 1, 1))[1])]"> <xsl:sort select="substring(name, 1, 1)"/> <h2><xsl:value-of select="substring(name, 1, 1)"/></h2> <ul> <!-- 该字母下的全部城市,按名称排序 --> <xsl:for-each select="key('cities-by-letter', substring(name, 1, 1))"> <xsl:sort select="name"/> <li><a href="{name_latin}"><xsl:value-of select="name"/></a></li> </xsl:for-each> </ul> </xsl:for-each> </body></html> </xsl:template> </xsl:stylesheet>

说明:

  • substring(name, 1, 1)取城市名首字母,<xsl:key>按首字母分组;
  • 外层for-each只处理每组第一个节点(Muenchian 去重),并对首字母xsl:sort;
  • 内层对同字母城市按name排序,<a href="{name_latin}">的属性值模板(AVT)直接把name_latin写入 href;
  • 在 libxslt 下substring()按 Unicode 字符处理,俄文首字母(А、Б、В、Е、И、К、М、Н、О、П、Р、С、Т、У、Х、Ч、Я 等)可正确分组排序;
  • 同样用XsltProcessor+DomDocument驱动执行,PHP 代码与任务四完全一致,仅替换 xsl 文件路径。

考点总结与应试建议

综合 5 个任务,这份测试题的考核矩阵可以归纳为四类能力:

  1. 递归与树形数据处理(任务一):邻接表建树、子树聚合计数、沿路径下钻渲染——这是核心题的灵魂,作答时优先保证"层级不限"与"数量为子树总数"这两个硬性行为正确;
  2. SQL 功底与向后兼容意识(任务一):能写出正确查询、能解释"为何允许加字段但必须回填",体现出对存量系统兼容性的工程素养;
  3. jQuery 插件工程化(任务二):$.fn扩展、$.extend默认值、this.each链式返回、相对坐标换算、批量发送与缓冲清空;
  4. 标准框架与模板技术(任务三~五):Yii 2.0 的标准路由/查询/Ajax 用法,以及 XSLT 1.0 的 key 索引、递归模板、Muenchian 分组等"服务端 XML 转换"技能。

提交建议:任务一务必附上基于 test-base.sql 的运行说明(数据库名、账号、PHP 执行方式),并把"与参考截图的 12/5/6/5 数量核对一致"作为自测清单;任务四、任务五保留好users.xml、cities.xml 与 xsl 文件的相对组织方式,便于评审直接复跑。题目所有原始要求与数据都可在 frontend/beboss/beboss-test-assignments.md 及其子目录中复核。

  • 教程

【免费下载链接】ru-test-assignments

Тестовые задания для самостоятельного выполнения от разных it компаний

项目地址:https://gitcode.com/gh_mirrors/ru/ru-test-assignments
点击查看免费下载

相关推荐

上一篇:MMDetection 之外:用 MMPose 在 WFLW 上训练 ResNet-50 + WingLoss 人脸关键点回归模型
下一篇:k-skill 韩国住宅公示价格查询指南:基于 housing-official-price 接入 realtyprice.kr 公开数据表面

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询