{{format('0')}} {{format('1214')}} {{format('4355')}}

【笔经】数字马力前端笔试-22应届 [ 笔经面经 ]

晚安月亮 文章 正文

挣钱给咖喱买最好吃的罐罐
分享

椰奶冻

{{nature("2022-07-26 22:03:12")}}更新

第一题

目标

使用 React, 参考下述需求优先级和设计稿 ,实现倒计时抢券组件。

关键需求点

  • 功能1: 按钮自动倒计时(此功能重要占比60%)
    • 进入页面时,卡片中的按钮开始自动 10s 倒计时
    • 倒计时过程中, 按钮显示剩余时间 (文案为: 10s、9s、8s、...、1s)
    • 倒计时结束后,按钮文案变为「 抢购
  • 功能2: 抢购功能模拟(此功能重要占比20%)
    • 点击抢购按钮时,调用异步模拟请求方法,请求完成后按钮文字变为「 已抢购
    • 异步请求模拟方法需自行实现,延迟 1s 后返回成功即可
  • 功能3: 还原券css样式(此功能重要占比20%)
    • 副标题最多支持2行, 多余2行省略号表示

设计稿

/**
 * 第一题
 */
import React, { FC, useEffect, useState } from 'react';
import './style.less';

/**
 * 渲染测试数据
 */
export const cardDataList: IDirectVoucher[] = [
  {
    title: '杭州市通用5元券',
    subTitle:
      '杭味面馆非常好吃,太好吃了,相当不错,味道鲜美,特别划算,快快抢购,聚划算',
  },
  {
    title: '杭州市10元券',
    subTitle: '兰州拉面非常好吃',
  },
];

/**
 * 券卡片渲染数据类型
 */
export interface IDirectVoucher {
  /** 标题 */
  title?: string;
  /** 副标题 */
  subTitle?: string;
}

export interface ICardProps {
  data: IDirectVoucher;
}

/**
 * 卡片组件
 */
export const Card: FC<ICardProps> = (props) => {
  // 在这里完成代码
  const { data } = props;
  const max = 10;
  const [str, setStr] = useState('抢购');
  const [count, setCount] = useState(max);

  // 倒计时逻辑
  // useEffect(() => {
  //   if (count >= 0) {
  //     setTimeout(() => {
  //       setCount(count - 1);
  //       if (count == 0) {
  //         setStr('抢购');
  //       } else {
  //         setStr(count + 's');
  //       }
  //     }, 1000);
  //   }
  // },[count]);

  useEffect(() => {
    if (count >= 0) {
      const interval = setInterval(() => {
        setCount(count - 1);
        if (count === 0) {
          setStr('抢购');
        } else {
          setStr(count + 's');
        }
      }, 1000);
      return () => clearInterval(interval);
    }
  });

  const timeClick = async () => {
    await setTimeout(function () {
      setStr('已抢购');
    }, 1000);
  };

  return (
    <div className="card">
      <div className="left">
        <div className="title">{data.title}</div>
        <div className="subTitle">{data.subTitle}</div>
      </div>
      <div className="right">
        <button onClick={() => timeClick()}>{str}</button>
      </div>
    </div>
  );
};

第二题

目标

实现一个 query 方法,实现对数据的链式查询和处理。

要求

  • query 传入参数为原始数据(数组格式,每个元素都是对象)
  • 通过进行链式调用对数据执行操作,支持的方法有
    • where(predicate): 根据参数的条件进行筛选,参数与 [].filter 的参数类似
    • orderBy(key, desc): 根据 key 的值进行排列,默认升序排列,当第二个参数为 true 时降序排列
    • groupBy(key): 根据 key 的值对数据元素进行分组,合并为二维数组
    • execute(): 执行所有处理并返回最终结果
  • 请结合下面示例理解需求
/**
 * 第二题
 */
import { isEqual } from 'lodash-es';

function query(data: Object[]) {
  let list = data;
  function myArray() {}
  // 判断数据类型
  if (Object.prototype.toString.call(data).slice(8, -1) !== 'Array') {
    return console.error('must be an array');
  }
  myArray.prototype.where = function (key) {
    list = list.filter(key);
    return { ...myArray.prototype };
  };
  myArray.prototype.orderBy = function (key) {
    list = list.sort((a, b) => a[key] - b[key]);
    return { ...myArray.prototype };
  };
  myArray.prototype.groupBy = function (key) {
    let group = list.reduce((pre, item) => {
      pre[item[key]] = [...(pre[item[key]] || []), item];
      return pre;
    }, {});
    let ordList = [];
    for (let key in group) {
      ordList.push(group[key]);
    }
    list = ordList;
    return { ...myArray.prototype };
  };
  myArray.prototype.execute = function (key) {
    return list;
  };
  return { ...myArray.prototype };
}

/**
 * 以下为测试用例,无需修改
 */
export default () => {
  try {
    const data = [
      { name: 'foo', age: 16, city: 'shanghai' },
      { name: 'bar', age: 24, city: 'hangzhou' },
      { name: 'fiz', age: 22, city: 'shanghai' },
      { name: 'baz', age: 19, city: 'hangzhou' },
    ];
    const result = query(data)
      // @ts-ignore
      .where((item) => item.age > 18)
      .orderBy('age')
      .groupBy('city')
      .execute();
    console.log('result:', result);

    if (
      !isEqual(result, [
        [
          { name: 'baz', age: 19, city: 'hangzhou' },
          { name: 'bar', age: 24, city: 'hangzhou' },
        ],
        [{ name: 'fiz', age: 22, city: 'shanghai' }],
      ])
    ) {
      throw new Error('Wrong answer');
    }
    return true;
  } catch (err) {
    console.warn('测试运行失败');
    console.error(err);
    return false;
  }
};
评论 0
0
{{userInfo.data?.nickname}}
{{userInfo.data?.email}}
TOP 2
【笔经】数字马力前端笔试-22应届

{{nature('2022-06-23 23:10:58')}} {{format('1214')}}人已阅读

TOP 3
【React】React组件卸载生命周期、路由跳转、页面关闭(刷新)拦截提示

{{nature('2023-02-03 16:12:08')}} {{format('1074')}}人已阅读

TOP 4
【antd】DatePicker组件不可选中时间段

{{nature('2022-09-16 11:11:28')}} {{format('466')}}人已阅读

TOP 5
【前端】css 实现两行或多行文本溢出显示省略号

{{nature('2023-05-25 10:42:41')}} {{format('398')}}人已阅读

目录

一言

# {{hitokoto.data.from || '来自'}} #
{{hitokoto.data.hitokoto || '内容'}}
作者:{{hitokoto.data.from_who || '作者'}}
自定义UI
配色方案

侧边栏