主頁 > 資料庫 > 詳細剖析|袋鼠云數堆疊前端框架Antd 3.x 升級 4.x 的踩坑之路

詳細剖析|袋鼠云數堆疊前端框架Antd 3.x 升級 4.x 的踩坑之路

2023-03-04 08:21:37 資料庫

袋鼠云數堆疊從2016年發布第?個版本開始,就始終堅持著以技術為核?、安全為底線、提效為?標、中臺為戰略的思想,堅定不移地?國產化信創路線,不斷推進產品功能迭代、技術創新、服務細化和性能升級,

在數堆疊過去的產品迭代中受限于當前組件的版本,積累了很多待解決的問題,隨著新的功能需求不斷增加,很多原先的組件以及互動設計需要進行優化,

2月,伴隨著數堆疊 UI5.0 的煥新升級,數堆疊前端團隊一起將組件框架 antd 從 v3.x 升級到了 v4.x,更新組件的 UI,提升產品的互動體驗,使數堆疊產品能夠更加靈活地適應未來產品功能迭代的需求,

本文將總結歸納袋鼠云數堆疊前端框架Antd 從3.x 升級到4.x 的相關步驟,及在這個程序中踩過的坑,解決的問題,

兼容性問題

第三方依賴兼容問題

· React - 最低 v16.9,部分組件使用 hooks 重構 ( react 升級相關檔案:https://sourl.cn/6bM4Ep)

· Less - 最低 v3.1.0,建議升級到 less 4.x;

· @ant-design/icons-antd - 不再內置 Icon 組件,請使用獨立的包,

對 3.x 的兼容性處理

或許是考慮到部分組件升級的毀壞性,antd4.x 中依然保留了對 3.x 版本的兼容,廢棄的組件通過 @ant-design/compatible 保持兼容,例如 Icon、Form,

注意:建議 @ant-design/compatible 僅在升級程序中稍作依賴,升級 4.x 請完全剔除對該過渡包的依賴,

升級步驟

只有一步

@ant-design/codemod-v4 自帶升級腳本,會自動替換代碼,

# 通過 npx 直接運行
npx -p @ant-design/codemod-v4 antd4-codemod apps/xxxx

# 或者全域安裝
# 使用 npm
npm i -g @ant-design/codemod-v4
# 或者使用 yarn
yarn global add @ant-design/codemod-v4

# 運行
antd4-codemod src

注意:該命令和腳本只會進行代碼替換,不會進行 AntD 的版本升級,需要手動將其升級至4.22.5,

該命令完成的作業:
    1. 將 Form 與 Mention 組件通過 @ant-design/compatible 包引入 
    2. 用新的 @ant-design/icons 替換字串型別的 icon 屬性值 
    3. 將 Icon 組件 + type =“” 通過 @ant-design/icons 引入 
    4. 將 v3 LocaleProvider 組件轉換成 v4 ConfigProvider 組件 
    5. 將 Modal.method() 中字串 icon 屬性的呼叫轉換成從 @ant-design/icons 中引入

antd4-codemod

file

上圖這類報錯是 Icon 組件自動替換錯誤,有 2 種處理方式:

· 報錯檔案的 Icon 比較少的情況,可以直接手動替換該檔案中的 Icon 組件,具體替換成 Icon 中的哪個組件可以根據 type 在 Icon 檔案中找( Icon檔案:https://sourl.cn/neHBVS );

· 下圖中是具體報錯的節點,可以看到 JSXSpreadAttribute 節點也就是拓展運算子中沒有 name 屬性,所以把 Icon 組件的拓展運算子改一下再執行替換腳本就可以了,

file

antd4 問題修復

styled-components

styled-components 依賴需要轉換寫法,

file

Icon

不要使用兼容包的 icon,
在 3.x 版本中,Icon 會全量引入所有 svg 圖示檔案,增加了打包產物;
在 4.x 版本中,對 Icon 進行了按需加載,將每個 svg 封裝成一個組件,

注意:antd 不再內置 Icon 組件,請使用獨立的包 @ant-design/icons,

· 使用

import { Icon } from 'antd';
mport { SmileOutlined } from '@ant-design/icons';

const Demo = () => (
  <div>
     <Icon type="smile" />
     <SmileOutlined />
     <Button icon={<SmileOutlined />} />
  </div>
);

· 兼容

import { Icon } from '@ant-design/compatible';
const Demo = () => (
  <div>
    <Icon type="smile" />
    <Button icon="smile" />
  </div>
);

Form

antd Form 從 v3 到 v4:https://sourl.cn/7TiRfp

● Form.create()

在 3.x 中,表單中任意一項的修改,都會導致 Form.create() 包裹的表單重新渲染,造成性能消耗;
在 4.x 中,Form.create() 不再使用,
如果需要使用 form 的 api,例如 setFieldsValue 等,需要通過 Form.useForm() 創建 Form 物體進行操作,

· 函陣列件寫法

// antd v4
const Demo = () => {
  const [form] = Form.useForm();

  React.useEffect(() => {
    form.setFieldsValue({
      username: 'Bamboo',
    });
  }, []);

  return (
    <Form form={form} {...props}> ... </Form>
  )
};

· 如果是 class component,也可以通過 ref 獲取

class Demo extends React.Component {
  formRef = React.createRef();

  componentDidMount() {
    this.formRef.current.setFieldsValue({
      username: 'Bamboo',
    });
  }

  render() {
    return (
      <Form ref={this.formRef}>
        <Form.Item name="username" rules={[{ required: true }]}>
          <Input />
        </Form.Item>
      </Form>
    );
  }
}

當我們使用 From.create() 的時候,可能會傳入引數,做資料處理,例如:

export const FilterForm: any = Form.create<Props>({
  onValuesChange: (props, changedValues, allValues) => {
    const { onChange } = props;
    onChange(allValues);
  },
})(Filter);

由于 Form.create 的洗掉,需要放到 < Form> 中,

<Form
  ref={this.formRef}
  layout="vertical"
  className="meta_form"
  onValuesChange={(_, allValues) => {
    const { onChange } = this.props;
    onChange(allValues);
  }}
>

● getFieldDecorator

在 4.x 中,不在需要 getFieldDecorator 對 Item 進行包裹,注意以下問題:

· 將之前寫在 getFieldDecorator 中的 name/rules 等移到屬性中;

· 初始化在 form 中處理,避免同名欄位沖突問題;

· 關于表單聯動的問題,官方提供了 shouldUpdate 方法,

const Demo = () => (
  <Form initialValues={{ username: 'yuwan' }}>
    <Form.Item name="username" rules={[{ required: true }]}>
      <Input />
    </Form.Item>
  </Form>
);

● initialValue

· 歷史問題

initialValue 從字面意來看,就是初始值 defaultValue,但是可能會有部分同學使用他的時候會誤以為 initialValue 等同于 value,造成這樣的誤解是因為在 3.x 的版本中,一直存在一個很神奇的問題,受控組件的值會跟隨 initialValue 改變,

看下面的例子,點擊 button 修改 username, input 框的 value 也會隨之改變,

const Demo = ({ form: { getFieldDecorator } }) => (
  const [username, setUsername] = useState('');
  const handleValueChange = () => {
    setUsername('yuwan');
  }
  return (
    <Fragment>
      <Form>
        <Form.Item>
          {getFieldDecorator('username', {
             initialValue: username,
             rules: [{ required: true }],
          })(<Input />)}
        </Form.Item>
      </Form>
      <Button onClick={handleValueChange}>Change</Button>
    </Fragment>
  )
);

const WrappedDemo = Form.create()(Demo);

但當 input 框被編輯過,initialValue 和 input 的系結效果就消失了,正確的做法應該是通過 setFieldsVlaue 方法去 set 值,

· 4.x 版本的 initialValue

在 4.x,antd 團隊已經把這個 bug 給解了,并且一是為了 name 重名問題,二是再次強調其初始值的功能,現在提到 Form 中了,當然,如果繼續寫在 Form. Item 中也是可以的,但需要注意優先級,

● shouldUpdate

前面有說過,form 表單不再會因為表單內部某個值的改變而重新渲染整個結構,而設有 shouldUpdate 為 true 的 Item,任意變化都會使該 Form. Item 重新渲染,

它會接收 render props,從而允許你對此進行控制,這里稍微注意一下,請勿在設定 shouldUpdate 的外層 Form. Item 上添加 name, 否則,你會得到一個 error,

<Form.Item shouldUpdate={(prev, next) => prev.name !== next.name}>
  {form => form.getFieldValue('name') === 'antd' && (
    <Form.Item name="version">
      <Input />
    </Form.Item>
  )}
</Form.Item>

在使用 shouldUpdate 的時候,需要在第一個 Form.Item 上加上 noStyle,否則就會出現下面這種留白占位的情況,

file

● validateTrigger

onBlur 時不再修改選中值,且回傳 React 原生的 event 物件,如果你在使用兼容包的 Form 且配置了 validateTrigger 為 onBlur ,請改至 onChange 以做兼容,

● validator

在 antd3 時,我們使用 callback 回傳報錯,但是 antd4 對此做了修改,自定義校驗,接收 Promise 作為回傳值,示例參考如下:

file

· antd3 的寫法

<FormItem label="具體時間" {...formItemLayout}>
  {getFieldDecorator('specificTime', {
    rules: [
      {
        required: true,
        validator: (_, value, callback) => {
          if (!value || !value.hour || !value.min) {
             return callback('具體時間不可為空');
          }
          callback();
        },
      },
    ],
  })(<SpecificTime />)}
</FormItem>

· antd4 的寫法

<FormItem
  label="具體時間"
  {...formItemLayout}
  name="specificTime"
  rules={[
    {
      required: true,
      validator: (_, value) => {
        if (!value || !value.hour || !value.min) {
            return Promise.reject('具體時間不可為空');
        }
        return Promise.resolve();
      },
    },
  ]}
>
  <SpecificTime />)
</FormItem>

● validateFields

不再支持 callback,該方法會直接回傳一個 Promise,可以通過 then / catch 處理,

this.formRef.validateFields()
  .then((values) => {
    onOk({ ...values, id: appInfo.id || '' });
})
  .catch(({ errorFields }) {
    this.formRef.scrollToField(errorFields[0].name);
  })

或者使用 async/await,

try {
  const values = await validateFields();
} catch ({ errorFields }) {
  scrollToField(errorFields[0].name);
}

● validateFieldsAndScroll

該 api 被拆分了,將其拆分為更為獨立的 scrollToField 方法,

onFinishFailed = ({ errorFields }) => {
  form.scrollToField(errorFields[0].name);
};

● form.name

在 antd 3.x 版本,系結欄位時,可以采用 . 分割的方式,如:

getFieldDecorator('sideTableParam.primaryKey')
getFieldDecorator('sideTableParam.primaryValue')
getFieldDecorator('sideTableParam.primaryName')

在最侄訓取 values 時,antd 3.x 的版本會對欄位進行匯總,得到如下:

const values = {
  sideTableParam: {
    primaryKey: xxx,
    primaryValue: xxx,
    primaryName: xxx,
  }
}

而在 antd 4.x下,會得到如下的 values 結果:

const values = {
  'sideTableParam.primaryKey': xxx,
  'sideTableParam.primaryValue': xxx,
  'sideTableParam.primaryName': xxx,
}

· 解決方法

在 antd 4.x 版本傳入陣列,

name={['sideTableParam', 'primaryKey']}
name={['sideTableParam', 'primaryValue']}
name={['sideTableParam', 'primaryName']}

使用 setFieldsValue 設定值:

setFieldsValue({
  sideTableParam: [
    {
      primaryKey: 'xxx',
      primaryValue: 'xxx',
      primaryName: 'xxx',
    },
  ],
});

當我們使用 name={['sideTableParam', 'primaryKey']} 方式系結值的時候,與其關聯的 dependencies/getFieldValue 都需要設定為['sideTableParam', 'primaryKey'],例如:

<FormItem dependencies={[['alert', 'sendTypeList']]} noStyle>
  {({ getFieldValue }) => {
    const isShowWebHook = getFieldValue(['alert', 'sendTypeList'])?.includes(
      ALARM_TYPE.DING
    );
   return (
     isShowWebHook &&
       RenderFormItem({
         item: {
           label: 'WebHook',
           key: ['alert', 'dingWebhook'],
           component: <Input placeholder="請輸入WebHook地址" />,
           rules: [
             {
               required: true,
               message: 'WebHook地址為必填項',
             },
           ],
           initialValue: taskInfo?.alert?.dingWebhook || '',
         },
       })
     );
  }}
</FormItem>

當我們希望通過 validateFields 拿到的資料是陣列時,例如這樣:

file

我們可以設定為這樣:

const formItems = keys.map((k: React.Key) => (
  <Form.Item key={k} required label="名稱">
    <Form.Item
      noStyle
      name={['names', k]}
      rules={[
        { required: true, message: '請輸入標簽名稱' },
        { validator: utils.validateInputText(2, 20) },
      ]}
    >
      <Input placeholder="請輸入標簽名稱" style={{ width: '90%', marginRight: 8 }} />
    </Form.Item>
     <i className="iconfont iconicon_deletecata" onClick={() => this.removeNewTag(k)} />
  </Form.Item>
));

● Tooltip

Form 支持屬性 tooltip,能夠在 label 后產生一個問號直接做提示,

file
file

● extra

針對于想放置于組件下面內容可以使用 extra 來實作,

file

<FormItem
  label="過濾條件"
  extra={
    <Tooltip title={customSystemParams}>
      系統引數配置&nbsp;
       <QuestionCircleOutlined />
     </Tooltip>
   }
>
  <Input.TextArea />
</FormItem>

● Form 在數堆疊的變化

通過這次 UI 升級和 antd 升級之后,Form 表單在數堆疊中的應用發生了較大的變化,從老版本的 label/component 橫向排版改為了縱向改版,在橫向空間不?的情況下,使?上下結構能有效提?填寫表單的效率,

file

Select

● rc-select

· 底層重寫

? 解決些許歷史問題

1)rc-select & rc-select-tree 的 inputValue & searchValue 之爭,rc-select-tree 是 rc-select 結合 tree 寫的一個組件,相似但又不同,searchValue 就是其中一點,也不是沒人提過 issue,只是人的忘性很大,時間長了就忘了、混淆了,導致在 rc-select 中甚至出現了 searchValue 的字樣,

2)inputValue 歷史問題,this.state.inputValue,

file

3)onSelect 清空了值,又會被 onChange 賦值回來,

? 模塊復用

在新版的 rc-select 中,antd 官方抽取了一個 generator 方法,它主要接收一個 OptionList 的自定義組件用于渲染下拉框部分,這樣我們就可以直接復用選擇框部分的代碼,而自定義 Select 和 TreeSelect 對應的串列或者樹形結構了,

● labelInValue

在 3.x 版本為 {key: string, label: ReactNode}

在 4.x 版本為 {value: string, label: ReactNode}

Table

● fixed

file

固定列時,文字過長導致錯位的問題,被完美解決了,

· 歷史原因

3.x 中對 table fixed 的實作,是寫了兩個 table, 頂層 fixed 的是一個,底層滾動的是一個,這樣出現這種錯位的問題就很好理解了,

要解決也不是沒有辦法,可以在特定的節點去測算表格列的高度,但是這個行為會導致重排,影響性能問題,

· 解決方案

4.x 中,table fixed 不在通過兩個 table 來實作,他使用了一個 position 的新特性:position: sticky;

元素根據正常檔案流進行定位,然后相對它的最近滾動祖先(nearest scrolling ancestor)和 containing block (最近塊級祖先 nearest block-level ancestor),包括 table-related 元素,基于 top、right、bottom 和 left 的值進行偏移,偏移值不會影響任何其他元素的位置,

優點:

? 根據正常檔案流進行定位

? 相對最近滾動祖先 & 最近塊級祖先進行偏移

缺點:

? 不兼容 <= IE11

解決了使用 absolute | fixed 脫離檔案流無法撐開高度的問題,也不再需要對高度進行測量,

● table.checkbox

· 問題描述

升級后,checkbox 寬度被擠壓了,

file

· 解決方案

通過在 rowSelection 中設定 columnWidth 和 fixed 解決,

const rowSelection = {
  fixed: true,
  columnWidth: 45,
  selectedRowKeys,
  onChange: this.onSelectChange,
};

● 渲染條件

antd4 Table 對渲染條件進行了優化,對 props 進行“淺比較”,如果沒有變化不會觸發 render,

● 類名更改

.ant-table-content 更改為 .ant-table-container

.ant-form-explain 更改為 .ant-form-item-explain

● dataIndex 修改

在 antd3.0 的時候,我們采用 user.userName 能夠讀到嵌套的屬性,

{
  title: '賬號',
  dataIndex: 'user.userName',
  key: 'userName',
  width: 200,
}

antd4.0 對此做了修改,同 Form 的 name,

{
  title: '賬號',
  dataIndex: ['user', 'userName'],
  key: 'userName',
  width: 200,
}

● table pagination showSizeChanger

· 問題描述

升級 antd4 后,發現一些表格分頁器多了 pageSize 切換的功能,代碼中 onChange 又未對 size 做處理,會導致底部分頁器 pageSize 和資料對不上,因此需要各自排查 Table 的 pagination 和 Pagination 組件,和請求串列介面的引數,

file

<Table
  rowKey="userId"
  pagination={{
  total: users.totalCount,
    defaultPageSize: 10,
  }}
  onChange={this.handleTableChange}
  style={{ height: tableScrollHeight }}
  loading={this.state.loading}
  columns={this.initColumns()}
  dataSource={users.data}
  scroll={{ x: 1100, y: tableScrollHeight }}
/>

handleTableChange = (pagination: any) => {
  this.setState(
    {
      current: pagination.current,
    },
    this.search
  );
};
search = (projectId?: any) => {
  const { name, current } = this.state;
  const { project } = this.props;
  const params: any = {
    projectId: projectId || project.id,
    pageSize: 10,
    currentPage: current || 1,
    name: name || undefined,
    removeAdmin: true,
  };
  this.loadUsers(params);
};

antd4.0 對此做了修改,同 Form 的 name,

<Table
  rowKey="userId"
  pagination={{
    showTotal: (total) => `共${total}條`,
    total: users.totalCount,
    current,
    pageSize,
  }}
  onChange={this.handleTableChange}
  style={{ height: tableScrollHeight }}
  loading={this.state.loading}
  columns={this.initColumns()}
  dataSource={users.data}
  scroll={{ x: 1100, y: tableScrollHeight }}
/>

handleTableChange = (pagination: any) => {
  this.setState(
    {
      current: pagination.current,
      pageSize: pagination.pageSize,
    },
    this.search
  );
};

search = (projectId?: any) => {
  const { name, current, pageSize } = this.state;
  const { project } = this.props;
  const params: any = {
    projectId: projectId || project.id,
    pageSize,
    currentPage: current || 1,
    name: name || undefined,
    removeAdmin: true,
  };
  this.loadUsers(params);
};

另外,一些同學在 Table 中既寫了 onChange,也寫了 onShowSizeChange,這個時候要注意,當切換頁碼條數的時候兩個方法都會觸發,onShowSizeChange 先觸發,onChange 后觸發,這個時候如果 onChange 內未對 pageSize 做處理可能導致切頁失敗,看下面代碼就明白了,寫的時候稍微注意一下即可,

file

● table sorter columnKey

file
· 問題描述

表格中如果要對表格某一欄位進行排序需要在 columns item 里設定 sorter 欄位,然后在 onChange 里拿到 sorter 物件進行引數處理,再請求資料,

需要注意的是,很多用到了 sorter.columnKey 來進行判斷,容易出現問題,sorter.columnKey === columns item.key,如果未設定 key,那么獲取到的 columnKey 就為空,導致搜索失效,要么設定 key,再進行獲取,同理, sorter.field === columns item.dataIndex,設定 dataIndex,通過 sorter.field 進行獲取,兩者都可以,

columns={
  [
    {
      title: '創建時間',
      dataIndex: 'gmtCreate1',
      key: 'aa',
      sorter: true,
      render(n: any, record: any) {
        return DateTime.formatDateTime(record.gmtCreate);
      }
    },
    ...
  ]
}
onChange={(pagination: any, filters: any, sorter: any) {
  console.log(pagination, '--pagination');
  console.log(filters, '--filters');
  console.log(sorter, '--sorter');
}}

● Table 在數堆疊的變化

通過這次 UI 升級和 antd 升級之后,表格在數堆疊中的應用發生了較大的變化,減?了表格默認?度,增加?屏可瀏覽的資料數量,

file

Tree

Tree 組件取消 value 屬性,現在只需要添加 key 屬性即可,

特別注意, 此問題會導致功能出問題,需要重點關注!!!

在專案中經常在 TreeItem 中增加引數,如:< TreeItem value=https://www.cnblogs.com/DTinsight/p/{value} data={data} >,在拖拽等回呼中就可以通過 nodeData.props.data 的方式獲取到 data 的值,但在 antd4 中,獲取引數的資料結構發生了改變,原先直接通過 props 點出來的不行了,

· 有兩種方式取值:

1)不使用props,直接采用 nodeData.data 的方式,也可以直接拿到,

2)繼續使用 props,在antd4中,還是可以通過 props 找到引數,只不過 antd 會把所有引數使用 data 進行包裹,就需要改成 nodeData.props.data.data,

· 新版資料結構如下:

file

· drag

拖拽節點位置的確定與 3.x 相比進行了變更,官網并沒有說明,具體如下圖:

file

左側為 3.x,右側為 4.x,
在3.x版本,只要把節點拖拽成目標節點的上中下,即代表著目標節點的同級上方,子集,同級下方;

在 4.x 版本,是根據當前拖拽節點與目標節點的相對位置進行確定最終的拖拽結果,

當拖拽節點處于目標節點的下方,且相對左側對齊的位置趨近于零,則最終的位置為目標節點的同級下方,

file

當拖拽節點處于目標節點的下方,且相對左側一個縮近的位置,則最終的位置為目標節點的子集,

file

當拖拽節點處于目標節點的上方,且相對左側對齊的位置趨近于零,則最終的位置為目標節點的同級上方,

file

Pagination

Pagination自 4.1.0 版本起,會默認將 showSizeChanger 引數設定為 true ,因而在資料條數超過50時,pageSize 切換器會默認顯示,這個變化同樣適用于 Table 組件,可通過 showSizeChanger: false 關閉,

如果 size 屬性值為 small,則洗掉 size 屬性,

Drawer

當我們在 Drawer 上 設定了 getContainer={false} 屬性之后,Drawer 會添加上 .ant-drawer-inline 的類名導致我們 position: fixed 失效,

file

Button

在 antd 3.0 中危險按鈕采用 type,

file

使用如下:涉及改動點 type、dangr 屬性,

file

Tabs

使標簽頁不被選中,

// 3.x
activeKey={undefined}
// 4.x
activeKey={null}

總結

該篇文章詳細講解了數堆疊前端團隊如何從 antd3 升級到 antd4 的詳細步驟,以及團隊在實踐程序中發現的一些問題和對應的解決方案,為后續產品的開發體驗打了基礎,也提供了一種更好的互動體驗,

未來數堆疊前端團隊將會持續關注產品體驗以及開發中的技術痛點,以開發更好的產品為導向,助力業務發展,
《資料治理行業實踐白皮書》下載地址:https://fs80.cn/380a4b

想了解或咨詢更多有關袋鼠云大資料產品、行業解決方案、客戶案例的朋友,瀏覽袋鼠云官網:https://www.dtstack.com/?src=https://www.cnblogs.com/DTinsight/p/szbky

同時,歡迎對大資料開源專案有興趣的同學加入「袋鼠云開源框架釘釘技術qun」,交流最新開源技術資訊,qun號碼:30537511,專案地址:https://github.com/DTStack

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/545776.html

標籤:大數據

上一篇:flink-綜合練習

下一篇:【MySQL速通篇001】5000字吃透MySQL部分重要知識點

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:33:24 more
  • MySQL中binlog備份腳本分享

    關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......

    uj5u.com 2023-04-20 08:28:06 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:27:27 more
  • 快取與資料庫雙寫一致性幾種策略分析

    本文將對幾種快取與資料庫保證資料一致性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ......

    uj5u.com 2023-04-20 08:26:48 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:26:35 more
  • 云時代,MySQL到ClickHouse資料同步產品對比推薦

    ClickHouse 在執行分析查詢時的速度優勢很好的彌補了MySQL的不足,但是對于很多開發者和DBA來說,如何將MySQL穩定、高效、簡單的同步到 ClickHouse 卻很困難。本文對比了 NineData、MaterializeMySQL(ClickHouse自帶)、Bifrost 三款產品... ......

    uj5u.com 2023-04-20 08:26:29 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:25:13 more
  • Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)

    Redis 報錯“OutOfDirectMemoryError(堆外記憶體溢位) ”問題如下: 一、報錯資訊: 使用 Redis 的業務介面 ,產生 OutOfDirectMemoryError(堆外記憶體溢位),如圖: 格式化后的報錯資訊: { "timestamp": "2023-04-17 22: ......

    uj5u.com 2023-04-20 08:24:54 more
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:24:03 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:23:11 more