产品设计杂感

news2024/10/7 8:21:39

概述

前面多篇文章提过我近一年以来几乎是一个人在负责一款数据产品,一款公司内部使用的报表开发工具。市面上的类似产品如Tableau,QuickBI等。工作角色(职责)包括:后端开发,前端开发,功能测试,需求对接(售前支持),用户对接(售后支持,问题排查),产品设计,数据清洗,报表开发等。

那这篇文章就讲讲关于产品设计的杂感,不凭空乱说,会附带讲述几个案例,因此会有大量截图。

案例

登录界面

这个登录功能之前是滑动验证码(早已被AI破解)来验证,因为公司内部使用企业微信昨晚通讯工具,故而考虑把滑动验证码登录校验改为4位(6位也行)随机数字密码(会发送到用户的企微上),相当于是手机短信验证码校验。不同的是,不用接入第三方付费短信平台,而使用免费且次数近乎无限量的企微消息推送功能。关于企微API的消息推送功能,参考企业微信消息推送。

另外,这个改造是另一个后端(职级比我高)和前端协作完成,后面此后端不再参与这个产品,此为背景。

用户类型有2种,99.99%的用户都是域账户,即使用域账号和开机密码完成登录,另外有极少量的用户为普通账户,即需要设置用户名和密码,密码password字段会保存在user表里,域账户不保存(如果保存,准备自己离职吧)。

在做角色及权限验证时,需要用到普通用户。所以登录功能需要支持普通用户在修改密码后依旧可以登录。

参考:基于antd pro的企微验证码登录功能(前后端)

cron

平台有如下4种功能:数据推送,数据监控,数据集,看板订阅邮件。其数据来源都是数据源,通过写SQL取数。另外,绝大多数的取数SQL依赖的数据源都是大数据平台(或叫数仓,不做概念上的严格区分),一般会有离线和实时数仓两类。离线一般是T+1,那就意味着数据推送(其他功能也是如此)需要有一个定时执行的概念。当然也有一次性执行后即可废弃的数据推送任务。提到定时任务,必然要涉及cron表达式,需要用户指定一个定时调度时间。

旧版平台是这样一种方式让用户来选择定时调度时间:
在这里插入图片描述
旧版的确实很简单,多个下拉列表,选择多个时间。但是,如果某个任务需要在0点到22点,共23个小时执行,则需要勾选23个选项,对于分钟也是一样,操作过于复杂。且,私以为这是上一代的产品设计。

于是新版平台,直接给一个输入框,改造如下:
在这里插入图片描述
绝大多数情况下,任务是每天执行一次的,如早上8点40分执行,写成:0 40 8 * * ?,简单明了。简洁才是美学。看看乔布斯商业帝国天才们设计的iPhone,iPod等产品,就大概知道什么叫美学吧。iPhone上手比Android难一些?但是习惯之后,不会再喜欢Android手机。

cron表达式对于不熟悉的人,的确有一点点上手难度。新版这个功能改造之后,前前后后有几个产品或商业分析同事用户反馈:不懂,不会,好难,怎么写,为啥不用旧版那种方式。给TA们一个链接,看过之后,几乎都会写cron表达式。

事实上,上面这个截图的交互设计做得足够人性化。不会写cron?没关系,点击右侧的链接,看看里面的文档,了解6个字符的概念解释,可以在线写cron并验证。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
排查下来,是前端组件对两个符号/-的支持问题。
在这里插入图片描述
比如现在从每天12时改成
在这里插入图片描述
改动不生效。应该还有其他情况

真是要多丑就有多丑
在这里插入图片描述

题外话

新入职的前端同学,在收到产品的功能改造需求后,上来就是一顿初生牛犊不怕虎精神,新增若干个文件:git add .,没有提前把整个项目结构和功能过一遍吗?
在这里插入图片描述
我们的平台产品不止一个功能(前面提到4个功能点)涉及到定时调度,也就是说代码是可以复用的,本来在Dataset目录下面有这些组件的,现在又在Autojob下面新增若干代码,增加项目维护复杂度(辛苦我之前复用若干前端组件和通用代码片段,删除重复的代码片段),Git代码库就是这样腐烂下去的。见如下截图:
在这里插入图片描述
再后来,前端又变更部署方式(本来不是好好的?为啥要改?背景未知),每次部署都需要把dist文件提交到gitlab,这是什么骚操作?
在这里插入图片描述
这样下去,Git代码库会越来越臃肿:
在这里插入图片描述
还有一个问题,前端项目启动特别慢,耗时10分钟左右才能启动成功,一直以来存在的问题。但是,只要应用启动成功后,不影响git checkout切换分支,可以实现前端代码热更新,几天甚至一两周都不需要重启,反正电脑又不关机。除非是新增依赖的组件,如watermark水印组件,必须要重启应用工程。

更换部署方式,启动慢的问题没有得到解决;增加dist目录后,不能切换分支。切换分支后,只能重新npm启动前端应用。WTF??

监控告警

在这里插入图片描述
在这里插入图片描述

设置一个定时调度时间点执行某个任务,如果执行失败,希望系统可以自动重试。

用户的痛点是:在设置的时间点跑任务,失败,自动重试一次后,成功。则第一次失败时,不要给用户发告警,否则用户需要登录系统,来进行后续操作。

然后产品介入的改造变成这样:

#iview数据推送监控#

预警名称:中国力量挽留弹窗_非小微
预警信息:
预警时间:2022-11-08 09:16:02

数据异常,请及时处理

在这里插入图片描述

去向API

产品功能背景如下:用户选择一个数据源,编写SQL,然后去向类型选择API(参考下面的截图),然后设置好定时任务的调度时间,即cron表达式。定时调度平台(XXL-Job)会定时把执行命令下发到任务执行逻辑所在的服务器节点。用户可通过调用平台提供的一个接口(这就是API的命名来源)获取SQL执行结果。为了保证接口响应性能,不可能在调用接口时,才去执行用户提交的几百行包括若干个子句的SQL。定时任务触发执行时,就会把SQL结果存储到MongoDB集群里。选择MongoDB原因无外乎,支持大对象存储,写入和查询性能极高,不像关系型数据库需要提前定义集合(表)结构,入门简单易于维护,可参考博主其他MongoDB相关专栏文章。而MongoDB的集合名字,是根据用户提交的SQL采用hash函数计算出一个唯一UUID。接口调用时,根据UUID去查询MongoDB的某个集合获取数据即可,保证接口的响应性能。另外,用户的SQL变更后,根据SQL内容生成的唯一UUID就会发生变更,此时一定要确保任务执行过一次;否则,就会出现调用接口时,根据最新的SQL去查找MongoDB集合失败,接口返回数据为空的问题。

改版前的用户界面设计如下:
在这里插入图片描述
题外话,上面这个截图里面有个是否缓存的单选框,这个需求和设计也是一个【产品】提出来的。本来最开始时是没有这个单选框。默认所有的SQL执行数据都会存储到MongoDB里。事后左思右想,半年多以前的自己为啥要接下这个需求?但是想不到原因。多干活,给老板留下干了事情的印象?完全没有必要啊,事实上本就做了很多事情。这个功能根本就是画蛇添足,多此一举。因为上线半年多,完全没有任何用户选不走缓存这种方式。

比如针对如下一个简单的SQL:

select 111 as userId, 222 as username

程序上,之前既有的逻辑是:根据上面的SQL生成一个唯一UUID,增加一个前缀。前缀名无所谓是啥,比如可以是job_api,那这个SQL对应的执行结果会存储在MongoDB的job_api_f5713c41222558fc25b95762b840adc8集合里面,这个集合的字段除了userIdusername之外,默认会追加几个字段,如_idapi_mongo_indexmongoDate等。并且在insert数据到MongoDB时,自动在api_mongo_index字段上面增加递增索引。事实上,MongoDB字段的主键_id字段上面也是有索引的。如果用户在根据任务ID获取存储在MongoDB集群里面的数据时,没有传参数filtering,则利用_id字段上面的索引快速拿到数据。如果接口的requestBody里面还有sort排序字段,则利用_idapi_mongo_index字段上面的索引快速拿到数据。如果接口的requestBody里面还有filtering(比如userId,只想获取某个用户的若干条数据)传参时,则查询时就会根据入参字段(userId)创建索引,第一次查询会比较慢,后面的查询就快了。

然后我们的【产品】设计如下,增加索引设定和出参设定:
在这里插入图片描述
索引设定,见名知义,是想要在MongoDB集合里面增加索引的字段。

而出参设定,则与前置SQL的查询字段息息相关。改造前,用户SQL里面的全部查询字段都会存储到MongoDB集合里;请求接口时,也会把全部字段吐出来。事实上,只要用户稍微具备一些常识,就不会在SQL里面写出select * from table_a这样的查询语句,而是把需要的字段,即请求接口时下游业务方需要的字段一一列出来。

一一列出需要的字段,其优势不言自明:

  1. 减少SQL执行耗时,减少IO;
  2. 减少MongoDB集合大小,节省存储空间;
  3. 减少请求接口时查询MongoDB集合时的耗时,减少IO;
  4. 减少接口responseBody,减少带宽。

所以,一般情况下,默认用户列出的查询字段就是用户想要的出参设定。在数仓开发中,经常会遇到大宽表,少则20个字段,多则70~80个字段。所以,哪怕是查询字段只有10个,一一勾选出参也是一个苦力活啊。但是呢,我们的项目负责人,产品,前端,后端(不是我,我肯定不会接这样的需求),测试,都没有发现这个改造页面上面需要增加一个全选框。
在这里插入图片描述
改造后的程序逻辑是:索引设定可以不勾选,出参设定必须选一个。不勾选索引设定,则接口请求时,即查询MongoDB集合时不走索引,也不走主键索引。

问题:

  1. 勾选索引设定指定的字段和filtering传参指定的字段不相同时,走不走索引,会不会自动创建索引?
  2. 接口请求时,filtering传参指定的字段变更时,走不走索引?

最后放两张截图证明这个改动纯属画蛇添足。改造前的接口响应耗时:
在这里插入图片描述
改造后的接口响应耗时:
在这里插入图片描述
响应变慢100个数量级啊。

需要手动一个个地修改用户的推送任务,选择使用哪些索引。笑死。

总结

小公司风格,小作坊氛围,确实可以塑造一个人全方面的能力。

如果最懂某个产品的人不能决定产品的发展方向,gg了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/77283.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32 bootloader简单实现的验证

目录 背景知识 STM32的启动模式 Flash memory的大小 实验验证 分区分配 bootloader代码 systeminit 背景知识 STM32的启动模式 STM32有三种启动模式, 这里验证的bootloader是通过Flash memory启动方式, 使用STM32内置的Flash,其首地址是0x08000000,一般我们…

[论文阅读] 颜色迁移-梯度保护颜色迁移

[论文阅读] 颜色迁移-梯度保护颜色迁移 文章: [Gradient-Preserving Color Transfer], [代码未公开] 本文目的: 如题所示为梯度保护的颜色迁移方法. 1-算法原理 人类的视觉系统对局部强度差异比强度本身更敏感, 因而, 保持颜色梯度是场景保真度的必要条件, 因而作者认为: 一…

python+django留守儿童爱心捐赠网站

开发语言:Python 框架:django Python版本:python3.7.7 数据库:mysql 数据库工具:Navicat11 开发软件:PyCharm 目录 1 绪论 1 1.1课题背景 1 1.2课题研究现状 1 1.3初步设计方法与实施方案 2 1.4本文研究…

城市应急处置系统实施目标

针对需求分析中的业务目标,本系统在实施中,通过 “两个工作台七个子系统”的目标来支撑业务目标,满足系统延续需求、功能需求、制度建设需求、平台拓展需求和技术性能需求。 具体分为事前6个子系统、事中2个工作台和事后1个子系统这三方面目标…

002:UIView

UIView简介: UIView作为最基础的视图类,起着管理屏幕上一定区域内容展示的作用。作为各种视图的父类,提供相应的基础能力。 外观、渲染和动画。相应区域内的事件。布局和管理子视图。 布局: 设置自身大小(size&…

[附源码]Python计算机毕业设计SSM基于农产品交易系统(程序+LW)

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

动态代理:JDK动态代理源码学习

文章目录前言概述什么是代理静态代理动态代理正文入口方法1:newProxyInstance方法2:getProxyClass0方法3:get 获取代理方法4:apply 创建代理方法5:generateProxyClass方法6:generateClassFile代理类总结前言…

LeetCode_动态规划_困难_1691.堆叠长方体的最大高度

目录1.题目2.思路3.代码实现(Java)1.题目 给你 n 个长方体 cuboids ,其中第 i 个长方体的长宽高表示为 cuboids[i] [widthi, lengthi, heighti](下标从 0 开始)。请你从 cuboids 选出一个子集 ,并将它们堆…

ubuntu14.04搭建openGrok 1.7.40 + Java17+tomcat10.0.27阅读android系统代码

为了快速阅读android系统代码,首选openGrok,其它SI或understand估计不适合了。 话不多说,工欲善其事必先利其器,先下载源码和工具. 以下命令默认使用root,防止权限问题 一、下载android 代码 还是清华的镜像比较牛…

农村金融专题-保险支出、收入、补贴各省份涉农贷款数据集

一、31省市农业保险赔付支出 1、数据来源:wind数据库 2、时间跨度:2005-2019年 3、区域范围:全国 4、指标说明: 部分数据如下: 二、各省农业保险保费收入 1、数据来源: 中国保险数据 2、时间跨度&…

「杂谈·II」cmp() 的参数类型应该是啥?

0. 引言 上了一节 DS 课,但是回到了初学 C 的内容…… 众所周知,最小生成树的 Kruskal 要用边表排序,通常是 sort() 配 cmp()。 而 cmp() 的两个参数的类型最好是什么呢? 让我们回到初学 C 的时候,温习一下知识…… 1…

MySQL数据库学习(3)

MySQL中select语句语法简单介绍&#xff1a; 基本语法规则&#xff1a; SELECT {* | <字段列名>} [FROM <表 1>, <表 2>… [WHERE <表达式> [GROUP BY <group by definition> [HAVING <expression> [{<operator> <expression>…

FineReport商业智能数据分析-下拉框控件

1. 概述 1.2 应用场景 「下拉框控件」可应用于填报、参数等场景&#xff0c;本文将介绍「下拉框控件」的属性及应用。 1.2.1 填报控件 填报报表中&#xff0c;可以用来在多个预备选项中选择一个值填入。如下图所示&#xff1a; 1.2.2 参数控件 参数面板处可以通过该控件过…

微服务框架 SpringCloud微服务架构 微服务保护 31 限流规则 31.4 流控效果【warm up】

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 微服务保护 文章目录微服务框架微服务保护31 限流规则31.4 流控效果【warm up】31.4.1 流控效果31.4.2 流控效果 - warm up31.4.3 案例31 限…

[论文阅读] 颜色迁移-Illuminant Aware Gamut-Based

[论文阅读] 颜色迁移-Illuminant Aware Gamut-Based 文章: [Illuminant Aware Gamut-Based Color Transfer], [python代码] 本文目的是提出一种新的颜色迁移算法, 可以感知光源变化的全色域颜色迁移方法. 1-算法原理 图像是由摄像机对光谱场景内容和场景照度的敏感性所产生…

springboot validated注解数据校验 异常处理

springboot validated 数据校验validated 数据校验简单的写一下这个用法啊&#xff0c;清晰的本篇文章就记录这个注解的一个用法。validated 数据校验 我们一般的数据校验是怎么用的&#xff1f;在常规模式下我们可能就是在前端去通过js去判断&#xff1f;还是在后端重新查找数…

【C语言字符串相关函数大全】

【C语言字符串相关函数大全】【1】atof【2】atoi【3】atol【4】isalnum【5】isdigit【6】islower【7】isupper【8】isprint【9】memchr【10】memcmp【11】memcpy【12】memset【13】strcat【14】strchr【15】strcmp【16】strpbrk【17】strstr【18】strtok【19】源码【20】源码执…

Mipmap的作用以及其优势和缺点

Mipmap的作用以及其优势和缺点 定义 Mipmap,又叫做多级渐进贴图纹理映射,作用在游戏的纹理贴图,根据渲染物体距离相机的远近,选用不同大小的纹理贴图; 作用 可以使得远处的像素不发生闪烁;减小带宽;减小带宽的原理 说到MipMap可能很多人都会觉得,只是开启后会增加内…

Vue3 学习笔记 —— 函数式编程、createVNode、render、h 函数

目录 2. createVNode()、render() 2.1 初步使用 createVNode()、render() 2.2 h 函数源码分析 3. 使用 h 函数的几种方法 3.1 h 函数 接收的参数 3.2 h 函数 使用方法 4. 通过 h 函数实现 button 组件 4.1 使用 props 接收传入组件的参数 4.2 使用 emit 向组件外发送事…

自动化运维工具—Ansible概述及命令行模块

一.自动化运维工具—Ansible概述及命令行模块 1.1 Ansible是什么 Ansible是一个基于Python开发的配置管理和应用部署工具&#xff0c;现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点&#xff0c;Pubbet和Saltstack能实现的功能&#xff0c;Ansible基本上都可…