当前位置: 首页 > news >正文

Shadcn UI 实战:打造可维护的企业级组件库

"我们真的需要自己写一套组件库吗?"上周的技术评审会上,我正在和团队讨论组件库的选型。作为一个快速发展的创业公司,我们既需要高质量的组件,又想保持灵活的定制能力。在对比了多个方案后,我们选择了 shadcn/ui 这个相对较新的解决方案。

说实话,最开始我对这个决定也有些担忧。毕竟相比 Ant Design 这样的成熟方案,shadcn/ui 的知名度确实不高。但经过一个月的实践,这个选择让我们收获了意外的惊喜。

为什么选择 shadcn/ui?

传统组件库给我们带来了一些困扰:

  • 样式难以深度定制
  • 打包体积大
  • 版本升级困难
  • 组件逻辑难以调整

就像租房和买房的选择一样,使用第三方组件库就像租房,虽然能快速入住,但想改造却处处受限。而 shadcn/ui 的方案,更像是买了一栋毛坯房,虽然需要自己装修,但能完全掌控每个细节。

项目实践

1. 初始化配置

首先,我们需要建立一个良好的组件开发基础:

// components.json
{"$schema": "https://ui.shadcn.com/schema.json","style": "default","rsc": true,"tailwind": {"config": "tailwind.config.js","css": "app/globals.css","baseColor": "slate","cssVariables": true},"aliases": {"components": "@/components","utils": "@/lib/utils"}
}// tailwind.config.js
const { fontFamily } = require('tailwindcss/defaultTheme')/** @type {import('tailwindcss').Config} */
module.exports = {darkMode: ['class'],content: ['app/**/*.{ts,tsx}', 'components/**/*.{ts,tsx}'],theme: {container: {center: true,padding: '2rem',screens: {'2xl': '1400px'}},extend: {colors: {border: 'hsl(var(--border))',input: 'hsl(var(--input))',ring: 'hsl(var(--ring))',background: 'hsl(var(--background))',foreground: 'hsl(var(--foreground))',primary: {DEFAULT: 'hsl(var(--primary))',foreground: 'hsl(var(--primary-foreground))'}},borderRadius: {lg: 'var(--radius)',md: 'calc(var(--radius) - 2px)',sm: 'calc(var(--radius) - 4px)'},fontFamily: {sans: ['var(--font-sans)', ...fontFamily.sans]}}}
}

2. 组件定制

shadcn/ui 最大的特点是它的组件是可以复制到项目中的。这让我们能够根据业务需求进行深度定制:

// components/ui/button.tsx
import * as React from 'react'
import { Slot } from '@radix-ui/react-slot'
import { cva, type VariantProps } from 'class-variance-authority'
import { cn } from '@/lib/utils'// 扩展按钮变体
const buttonVariants = cva('inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50', {variants: {variant: {default: 'bg-primary text-primary-foreground hover:bg-primary/90',destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',outline: 'border border-input hover:bg-accent hover:text-accent-foreground',secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',ghost: 'hover:bg-accent hover:text-accent-foreground',link: 'underline-offset-4 hover:underline text-primary',// 添加自定义变体brand: 'bg-brand-500 text-white hover:bg-brand-600',success: 'bg-green-500 text-white hover:bg-green-600'},size: {default: 'h-10 px-4 py-2',sm: 'h-9 rounded-md px-3',lg: 'h-11 rounded-md px-8',icon: 'h-10 w-10'}},defaultVariants: {variant: 'default',size: 'default'}
})// 扩展按钮属性
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {asChild?: booleanloading?: booleanicon?: React.ReactNode
}const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(({ className, variant, size, asChild = false, loading, icon, children, ...props }, ref) => {const Comp = asChild ? Slot : 'button'return (<Comp className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props}>{loading && <LoadingSpinner className='mr-2 h-4 w-4 animate-spin' />}{icon && <span className='mr-2'>{icon}</span>}{children}</Comp>)
})
Button.displayName = 'Button'

3. 主题定制

我们实现了一个灵活的主题切换系统:

// lib/themes.ts
export const themes = {light: {'--background': '0 0% 100%','--foreground': '222.2 84% 4.9%','--primary': '222.2 47.4% 11.2%','--primary-foreground': '210 40% 98%'// ... 其他颜色变量},dark: {'--background': '222.2 84% 4.9%','--foreground': '210 40% 98%','--primary': '210 40% 98%','--primary-foreground': '222.2 47.4% 11.2%'// ... 其他颜色变量},// 添加自定义主题brand: {'--background': '0 0% 100%','--foreground': '222.2 84% 4.9%','--primary': '220 90% 56%','--primary-foreground': '210 40% 98%'}
}// components/theme-provider.tsx
const ThemeProvider = ({ children }: { children: React.ReactNode }) => {const [theme, setTheme] = useState('light')useEffect(() => {const root = document.documentElementconst themeVars = themes[theme as keyof typeof themes]Object.entries(themeVars).forEach(([key, value]) => {root.style.setProperty(key, value)})}, [theme])return <ThemeContext.Provider value={{ theme, setTheme }}>{children}</ThemeContext.Provider>
}

4. 组件封装

基于 shadcn/ui 的基础组件,我们封装了一些业务组件:

// components/business/data-table.tsx
import { Table } from '@/components/ui/table'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { useState } from 'react'interface DataTableProps<T> {data: T[]columns: Column[]onEdit?: (record: T) => voidonDelete?: (record: T) => void
}export function DataTable<T>({ data, columns, onEdit, onDelete }: DataTableProps<T>) {const [searchText, setSearchText] = useState('')const filteredData = data.filter(record =>columns.some(column => {const value = record[column.key as keyof T]return String(value).toLowerCase().includes(searchText.toLowerCase())}))return (<div className='space-y-4'><div className='flex justify-between'><Input placeholder='搜索...' value={searchText} onChange={e => setSearchText(e.target.value)} className='max-w-sm' /></div><Table><Table.Header>{columns.map(column => (<Table.Column key={column.key}>{column.title}</Table.Column>))}<Table.Column>操作</Table.Column></Table.Header><Table.Body>{filteredData.map((record, index) => (<Table.Row key={index}>{columns.map(column => (<Table.Cell key={column.key}>{record[column.key as keyof T]}</Table.Cell>))}<Table.Cell><div className='space-x-2'>{onEdit && (<Button size='sm' variant='outline' onClick={() => onEdit(record)}>编辑</Button>)}{onDelete && (<Button size='sm' variant='destructive' onClick={() => onDelete(record)}>删除</Button>)}</div></Table.Cell></Table.Row>))}</Table.Body></Table></div>)
}

实践效果

经过一个月的使用,我们获得了显著的收益:

  1. 打包体积减少了 60%
  2. 组件定制更加灵活
  3. 开发效率提升
  4. 代码可维护性增强

最让我印象深刻的是一位同事说:"终于可以随心所欲地修改组件了,不用再为覆盖第三方样式发愁。"

经验总结

使用 shadcn/ui 的过程让我们学到:

  1. 组件库不一定要追求"拿来即用"
  2. 掌控组件源码比黑盒封装更有优势
  3. 样式系统的一致性很重要
  4. 渐进式地构建组件库是个好方法

就像装修房子,虽然前期投入较大,但最终得到的是一个完全符合需求的解决方案。

写在最后

shadcn/ui 给了我们一个全新的视角:组件库可以是一系列最佳实践的集合,而不仅仅是一个封装好的产品。正如那句话说的:"授人以鱼不如授人以渔",shadcn/ui 不仅给了我们组件,更教会了我们如何构建组件。

有什么问题欢迎在评论区讨论,让我们一起探讨组件库开发的更多可能!

如果觉得有帮助,别忘了点赞关注,我会继续分享更多实战经验~

相关文章:

Shadcn UI 实战:打造可维护的企业级组件库

"我们真的需要自己写一套组件库吗&#xff1f;"上周的技术评审会上,我正在和团队讨论组件库的选型。作为一个快速发展的创业公司,我们既需要高质量的组件,又想保持灵活的定制能力。在对比了多个方案后,我们选择了 shadcn/ui 这个相对较新的解决方案。 说实话,最开始…...

C#速成(GID+图形编程)

常用类 类说明Brush填充图形形状,画刷GraphicsGDI绘图画面&#xff0c;无法继承Pen定义绘制的对象直线等&#xff08;颜色&#xff0c;粗细&#xff09;Font定义文本格式&#xff08;字体&#xff0c;字号&#xff09; 常用结构 结构说明Color颜色Point在平面中定义点Rectan…...

CMD使用SSH登陆Ubuntu

1.确认sshserver是否安装好 ps -e | grep sshd 450 ? 00:00:00 sshd 2、如果看到sshd那说明ssh-server已经启动了 其实在/etc/ssh下有一个sshd_config 文件。对这个文件进行修改vim sshd_config。 往文件中添加如下内容&#xff1a; Port 22 Protocol 2 PermitRootLogin yes P…...

Fay环境安装及使用

一、项目源码 代码地址 &#xff1a; Fay 2D数字人源码地址&#xff1a;xuniren LLM用是清华开源的ChatGLM源码地址&#xff1a;ChatGLM-6B 模型地址chatglm2-6b-int4 &#xff08;大模型的安装直接参考了我的另一篇文章&#xff1a;ChatGLM2-6B-int4的…...

重写 `equals` 和 `hashCode` 的一致性

重写 equals 和 hashCode 的一致性 在 Java 中&#xff0c;当我们重写 equals 方法时&#xff0c;通常需要同时重写 hashCode 方法&#xff0c;以确保对象在逻辑上相等时&#xff0c;其哈希值也相等。这是一种重要的契约&#xff08;contract&#xff09;&#xff0c;主要用于…...

【游戏设计原理】14 - MDA:游戏的机制、运行和体验

1. 学习、分析并总结 MDA 原理 MDA (Mechanics, Dynamics, and Aesthetics) 是一种用来分析和理解游戏设计的框架&#xff0c;由 Marc LeBlanc, Robin Hunicke, 和 Robert Zubek 提出。这个框架将游戏分解为三个核心要素&#xff1a; Mechanics&#xff08;机制&#xff09;&…...

鸿蒙Next创建自定义组件总结

一、引言 在鸿蒙Next开发中&#xff0c;自定义组件是构建高效、可维护UI的重要组成部分。它具有可组合、可重用以及数据驱动UI更新等特点&#xff0c;能帮助开发者更好地实现代码复用、业务逻辑与UI分离等目标。本文将详细总结创建自定义组件的相关知识&#xff0c;包括其基本…...

redis 缓存使用

工具类 package org.springblade.questionnaire.redis;import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factor…...

Javascript面试手撕常见题目(回顾一)

1.JS查找文章中出现频率最高的单词? 要在JavaScript中查找文章中出现频率最高的单词&#xff0c;你可以按照以下步骤进行操作&#xff1a; 将文章转换为小写&#xff1a;这可以确保单词的比较是大小写不敏感的。移除标点符号&#xff1a;标点符号会干扰单词的计数。将文章拆…...

lc146LRU缓存——模仿LinkedHashMap

146. LRU 缓存 - 力扣&#xff08;LeetCode&#xff09; 法1&#xff1a; 调用java现有的LinkedHashMap的方法&#xff0c;但不太理解反正都不需要扩容&#xff0c;super(capacity, 1F, true);不行吗&#xff0c;干嘛还弄个装载因子0.75还中途扩容一次浪费时间。 class LRUC…...

【C语言】头文件

所有学习过C语言的朋友都熟悉这样一段代码&#xff1a; #include <stdio.h>int main(int argc, char *argv[]) {return 0; }那么&#xff0c;你真的了解 <stdio.h> 吗&#xff1f; <stdio…...

WSL (Windows Subsystem for Linux)

文章目录 Windows下使用Linux的三种方式&#xff1a;1.WSL(1)安装WSL(2)初始化Linux系统(3)安装、创建、激活 Python虚拟环境 2.虚拟机3.Docker Windows下使用Linux的三种方式&#xff1a; 1.WSL 是最简单的在 Windows 上运行 Linux 环境的方式&#xff0c;适用于日常开发和命…...

[Java] 使用 VSCode 来开发 Java

目录 前言Java 环境怎么看自己是否已经配置完成&#xff1f;安装 JDK安装 Maven 环境修改 Maven 依赖源 完善 VS Code配置插件配置 Maven配置 Maven Settings配置 Maven 可执行文件地址 前言 由于使用 VSCode 编码已经成为习惯&#xff0c;并且它确实相对其他的 IDE 较为轻量化…...

机器学习之偏差

机器学习中的偏差&#xff08;Bias&#xff09;是指模型的预测值与真实值之间的系统性误差&#xff0c;或者说模型无法准确捕捉数据中复杂模式的能力。偏差通常与模型的假设或学习能力有关&#xff0c;过高的偏差会导致模型的性能不佳&#xff0c;表现为欠拟合。 偏差的来源 模…...

微信小程序处理交易投诉管理,支持多小程序

大家好&#xff0c;我是小悟 1、问题背景 玩过微信小程序生态的&#xff0c;或许就有这种感受&#xff0c;如果收到投诉单&#xff0c;不会及时通知到手机端&#xff0c;而是每天早上10:00向小程序的管理员及运营者推送通知。通知内容为截至前一天24时该小程序账号内待处理的交…...

在C#中测试比较目录的不同方法以查看它们有哪些共同的文件

C# 中的示例“比较目录以查看它们有哪些共同的文件”使用Directory.GetFiles获取两个目录中的文件。它对文件进行排序&#xff0c;并比较两个排序后的列表以查看哪些文件位于第一个目录中、第二个目录中或两个目录中。有关其工作原理的详细信息&#xff0c;请参阅该示例。 Kur…...

2D gaussian splatting的配置和可视化

继3D gaussian splatting&#xff0c;2D gaussian splatting除了渲染新视角&#xff0c;还能够生成mesh模型。 2D gaussian splatting的配置 两者的运行环境基本一致 GitHub - hbb1/2d-gaussian-splatting: [SIGGRAPH24] 2D Gaussian Splatting for Geometrically Accurate …...

git分支管理

目录 1.Git分支管理1.1 分支创建1.2 分支删除1.3 分支合并1.4 分支的本质1.5 分支的冲突 2.Git stash2.1 git stash 3.分支管理策略3.1主分支3.2辅助分支3.3Feature分支3.4release分支3.5bugfix分支 1.Git分支管理 Git 的默认分支就是 master。你所作的commit会在master分支上…...

【Elasticsearch入门到落地】4、Elasticsearch的安装

接上篇《3、es与mysql的概念对比》 上一篇我们学习了Elasticsearch与Mysql的概念与区别。本篇我们来进行Elasticsearch的环境准备及软件安装。 一、环境准备 如果我们没有自己的Linux服务器&#xff0c;且现在正在使用的是Windows操作系统的电脑&#xff0c;那么首先我们需要安…...

如何在谷歌浏览器中开启安全浏览

在数字化时代&#xff0c;网络安全变得愈发重要。作为全球最受欢迎的网络浏览器之一&#xff0c;谷歌浏览器提供了多种功能来保护用户的在线安全。本文将详细介绍如何在谷歌浏览器中开启安全浏览&#xff0c;并额外提供一些有用的页面滚动设置、地址栏快捷搜索和跟踪防护的相关…...

短视频矩阵贴牌:打造品牌新势力的策略与实践

在数字化浪潮席卷全球的今天&#xff0c;短视频以其独特的魅力迅速崛起&#xff0c;成为连接用户与品牌的重要桥梁。企业为了快速抢占市场&#xff0c;提升品牌影响力&#xff0c;纷纷探索短视频矩阵贴牌这一新兴模式。本文将深入探讨短视频矩阵贴牌的概念、优势、实施流程及注…...

【潜意识Java】javaee中的SpringBoot在Java 开发中的应用与详细分析

目录 一、前言 二、Spring Boot 简介 三、Spring Boot 核心模块 四、Spring Boot 项目实战&#xff1a;构建一个简单的 RESTful API 1. 创建 Spring Boot 项目 2. 配置数据库 3. 创建实体类 4. 创建 JPA 仓库接口 5. 创建服务层 6. 创建控制器层 7. 测试 API 8. 运…...

linux basics

本篇文章旨在为网络安全初学者介绍linux操作系统基础。通过阅读本文&#xff0c;读者将能够对linux系统有一个初步的了解 一、openssl 1、命令&#xff1a; openssl passwd -1 123 -l参数指定使用MD5加密算法对密码"123"进行加密处理。MD5是一种常用的哈希算法,它将…...

[OpenGL] Transform feedback 介绍以及使用示例

一、简介 本文介绍了 OpenGL 中 Transform Feedback 方法的基本概念和代码示例。 二、Transform Feedback 介绍 1. Transform Feedback 简介 根据 OpenGL-wiki&#xff0c;Transform Feedback 是捕获由顶点处理步骤&#xff08;vertex shader 和 geometry shader&#xff0…...

pytorch_fid 安装笔记

目录 torch安装&#xff1a; pytorch_fid安装 torch安装&#xff1a; pip install torch2.5.0 --index-url https://download.pytorch.org/whl/cu121 pytorch_fid安装 pip install pytorch_fid 安装后&#xff0c;torch也会自动安装&#xff0c;导致torch引用报错。...

SAM大模型实践(一)

参考着segment-geospatial 项目主页的介绍&#xff0c;尝试复现一下Example-satallite的案例。 Satellite - segment-geospatialhttps://samgeo.gishub.org/examples/satellite/ 过程当中遇到了一些坑给大家做点分享&#xff0c;主要有几种情况&#xff0c;一个是torch…...

数据结构 ——前缀树查词典的实现

数据结构 ——前缀树查词典的实现 一、前缀树的概念 前缀树是一种多叉树结构&#xff0c;主要用于存储字符串。每个节点代表一个字符&#xff0c;路径从根节点到叶节点表示一个完整的字符串。前缀树的关键特征是 共享前缀&#xff0c;也就是说&#xff0c;如果两个字符串有相…...

边缘智能创新应用大赛获奖作品系列一:智能边缘计算✖软硬件一体化,开启全场景效能革命新征程

边缘智能技术快速迭代&#xff0c;并与行业深度融合。它正重塑产业格局&#xff0c;催生新产品、新体验&#xff0c;带动终端需求增长。为促进边缘智能技术的进步与发展&#xff0c;拓展开发者的思路与能力&#xff0c;挖掘边缘智能应用的创新与潜能&#xff0c;高通技术公司联…...

修改ubuntu apt 源及apt 使用

视频教程:修改ubuntu apt 源和apt 使用方法_哔哩哔哩_bilibili 1 修改apt源 1.1 获取阿里云ubuntu apt 源 https://developer.aliyun.com/mirror/ubuntu?spma2c6h.13651102.0.0.3e221b11mqqLBC 1.2 修改apt 源 vim /etc/apt/sources.list deb https://mirrors.aliyun.com/ub…...

Kafka 磁道寻址过程详解

前言 Apache Kafka 是一款高吞吐、分布式的消息流平台&#xff0c;广泛应用于实时数据处理和事件驱动系统。在 Kafka 中&#xff0c;消息是存储在磁盘上的&#xff0c;这种高效的数据读写性能得益于 Kafka 独特的磁盘存储架构和寻址机制。本文将从 Kafka 的存储结构、磁道寻址…...

GEE+本地XGboot分类

GEE本地XGboot分类 我想做提取耕地提取&#xff0c;想到了一篇董金玮老师的一篇论文&#xff0c;这个论文是先提取的耕地&#xff0c;再做作物分类&#xff0c;耕地的提取代码是开源的。 但这个代码直接在云端上进行分类&#xff0c;GEE会爆内存&#xff0c;因此我准备把数据下…...

安防监控Liveweb视频汇聚融合平台助力执法记录仪高效使用

Liveweb平台可接入的设备除了常见的智能分析网关与摄像头以外 &#xff0c;还可通过GB28181协议接入执法记录仪&#xff0c;实现对执法过程的全程监控与录像&#xff0c;并对执法轨迹与路径进行调阅回看。那么&#xff0c;如何做到执法记录仪高效使用呢&#xff1f; 由于执法记…...

酷盾安全:Edge SCDN边缘安全内容分发网络

在当今数字化迅猛发展的时代&#xff0c;互联网内容分发的高效与安全成为了企业不可忽视的重要课题。为了满足这一需求&#xff0c;酷盾安全推出了创新的Edge Secure Content Delivery Network&#xff08;Edge Scdn&#xff09;解决方案&#xff0c;它不仅融合了分布式DDoS防护…...

决策引擎技术

决策引擎&#xff08;Decision Engine&#xff09;是一种用于自动化决策过程的软件系统。它通常用于处理复杂的业务逻辑&#xff0c;根据输入的数据和预定义的规则或模型来做出决策。决策引擎在许多领域都有广泛的应用&#xff0c;如金融、保险、医疗、供应链管理等。 在Java中…...

Servlet学习中遇到的一些问题及解决

错误&#xff1a;JavaWeb-错误&#xff1a;类xxx不是Servlet 解决&#xff1a;可能是Tomcat版本不匹配导致&#xff0c;更换Tomcat版本解决问题 错误&#xff1a;在自定义的Servlet类中不能添加 WebServlet 注解 解决&#xff1a;可能是WebServlet版本不匹配&#xff0c;更换…...

oracle开窗函数笔记、over()笔记

文章目录 开窗函数、组函数、分析函数概念聚合函数和分析函数的区别partition by后面也可以跟多个字段 开窗函数一定要加 聚合函数、或分析函数吗&#xff0c;否则会报错lag()和lead()的用法lag和lead实战开窗函数可以和其他函数一起使用吗? TODO开窗函数中的count(1)是什么意…...

深度学习面试相关-2024.12.15记录

深度学习 面试相关- 2024.12.15记录 目录 深度学习 面试相关- 2024.12.15记录整体常问问题1数学基础1.1 概率统计1.2 线代 2机器学习算法2.1 深度学习算法2.2 机器学习算法 整体常问问题 https://www.nowcoder.com/discuss/353154899112304640 1数学基础 1.1 概率统计 htt…...

CSS|07 标准文档流

标准文档流 一、什么是标准文档流 在制作的 HTML 网页和 PS 画图软件画图时有本质上面的区别: HTML 网页在制作的时候都得遵循一个“流的规则:从左至右、从上至下。 使用 Ps 软件画图时可以在任意地方画图。 <!DOCTYPE html> <html lang"en"> <hea…...

1 JVM JDK JRE之间的区别以及使用字节码的好处

JDK jdk是编译java源文件成class文件的&#xff0c;我们使用javac命令把java源文件编译成class文件。 我们在java安装的目录下找到bin文件夹&#xff0c;如下图所示: 遵循着编译原理&#xff0c;把java源文件编译成JVM可识别的机器码。 其中还包括jar打包工具等。主要是针对…...

ubuntu安装8812au驱动却无法加载网卡的问题

驱动GIT地址 https://github.com/aircrack-ng/rtl8812au按照里面提示安装驱动 输入 sudo dkms status查看驱动是否安装成功 接入网卡&#xff0c;看看ifconfig能否输出网卡 如果不行 使用sudo dmesg -w插拔网卡看看输出 如果输出为: load module with unavailable key is …...

Eureka学习笔记-服务端

Eureka学习笔记 服务端 模块设计 Resources &#xff1a;这部分对外暴露了一系列的 Restful 接口。Eureka Client 的注册、心跳、获取服务列表等操作都需要调用这些接口。另外&#xff0c;其他的 Server 在同步 Registry 时也需要调用这些接口。Controller &#xff1a;这里提…...

LangChain

文章目录 一、LangChain 是什么&#xff1f;二、核心概念1. LLM Wrappers2. Prompt Templates3. Indexes4. Chains5. Agents 三、工作流程四、应用场景示例一&#xff1a;简单的语言模型调用示例二&#xff1a;使用Prompt Templates&#xff08;提示模板&#xff09;示例三&…...

搭建分布式Hive集群

title: 搭建分布式Hive集群 date: 2024-11-29 23:39:00 categories: - 服务器 tags: - Hive - 大数据搭建分布式Hive集群 本次实验环境&#xff1a;Centos 7-2009、Hadoop-3.1.4、JDK 8、Zookeeper-3.6.3、Mysql-5.7.38、Hive-3.1.2 功能规划 方案一&#xff08;本地运行模…...

Scala的惰性求值:深入理解与实践

在编程中&#xff0c;我们经常需要处理那些计算成本高昂或者可能永远不会用到的值。在这种情况下&#xff0c;惰性求值&#xff08;Lazy Evaluation&#xff09;是一种非常有用的策略。它允许我们推迟计算&#xff0c;直到这些值真正需要被使用。Scala&#xff0c;作为一种多功…...

游戏引擎学习第54天

仓库: https://gitee.com/mrxiao_com/2d_game 回顾 我们现在正专注于在游戏世界中放置小实体来代表所有的墙。这些实体围绕着世界的每个边缘。我们有活跃的实体&#xff0c;这些实体位于玩家的视野中&#xff0c;频繁更新&#xff0c;而那些离玩家较远的实体则以较低的频率运…...

QT绘制同心扇形

void ChartForm::paintEvent(QPaintEvent *) {QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);// 设置抗锯齿painter.save();// 设置无边框&#xff08;不需要设置QPen&#xff0c;因为默认是不绘制边框的&#xff09;QPen pen(Qt::NoPen);// QPen pen…...

梳理你的思路(从OOP到架构设计)_浅尝架构师的滋味02

目录 1、 App开发者的职责&#xff1a;买主提供需求知识&#xff0c;App开发者帮他写代码 撰写的代码 撰写代码&#xff0c;将装配(扩充)到 2、 从生活中体会 基於軟硬整合觀點“两种知识” ​编辑 1、 App开发者的职责&#xff1a;买主提供需求知识&#xff0c;App开发者帮…...

使用VLC 搭建 RTSP 服务器

第一步&#xff1a;打开 VLC &#xff0c;媒体--->流 第二步&#xff1a;添加一个选择本地的文件&#xff0c;然后点击选择"串流" 第三步&#xff1a;确认你选择的文件&#xff0c;然后点击下一个 第四步&#xff1a; 配置 选择的视频文件使用哪种 流输出&#xf…...

什么是大型语言模型

大型语言模型简介 大型语言模型 (LLM) 是一种深度学习算法&#xff0c;可以使用非常大的数据集识别、总结、翻译、预测和生成内容。 NVIDIA 开发者计划 想要了解有关 NIM 的更多信息&#xff1f;加入 NVIDIA 开发者计划&#xff0c;即可免费访问任何基础设施云、数据中心或个…...

游卡,科锐国际,蓝禾,汤臣倍健,顺丰,途游游戏25秋招内推

游卡&#xff0c;科锐国际&#xff0c;蓝禾&#xff0c;汤臣倍健&#xff0c;顺丰&#xff0c;途游游戏25秋招内推 ①科锐国际25届秋招补录 人力资源类岗位&#xff0c;补录城市&#xff1a;上海&#xff0c;苏州&#xff0c;锦州&#xff1b;全日制公办本科及以上 25届应届毕业…...