AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

【故障現場】控制好取值范圍,甭給別人犯錯的機會

來源: 責編: 時間:2023-12-11 09:25:13 256觀看
導讀1. 問題&分析1.1. 案例小艾剛剛和大飛哥炒了一架,心情非常低落。整個事情是這樣,小艾前段時間剛剛接手訂單系統,今天收到一大波線上 NPE (Null Pointer Exception)報警,經排查發現訂單表的商品類型(ProductType)出現一組非法

1. 問題&分析

1.1. 案例

小艾剛剛和大飛哥炒了一架,心情非常低落。整個事情是這樣,小艾前段時間剛剛接手訂單系統,今天收到一大波線上 NPE (Null Pointer Exception)報警,經排查發現訂單表的商品類型(ProductType)出現一組非法值,在展示訂單時由于系統無法識別這些非法值導致空指針異常。小艾通過排查,發現訂單來自于市場團隊,于是找到團隊負責人大飛哥,并把現狀和排查結果進行同步。經過大飛哥的排查,確實是在前端的各種跳轉過程中導致 商品類型參數 被覆蓋,立即安排緊急上線進行修復。整個事情處理速度快也沒造成太大損失,但在事故復盤過程中出現了偏差:pIj28資訊網——每日最新資訊28at.com

  1. 小艾認為核心問題是調用方沒有按規范進行傳參,所以主要責任在大飛哥;
  2. 大飛哥則認為是訂單系統未對輸入參數進行有效性校驗,致使問題數據存儲至數據庫,才出現后續的各種問題,所以主要責任在小艾;

兩人各持己見爭論不休,你認為責任在誰呢?pIj28資訊網——每日最新資訊28at.com

1.2. 問題分析

在訂單系統中,商品類型定義為 Integer 類型,使用靜態常量來表示系統所支持的具體值,核心代碼如下:pIj28資訊網——每日最新資訊28at.com

// 領域對象public class OrderItem{    private Integer productType;}// 定義 ProductTypes 管理所有支持的 ProductTypepublic class ProductTypes{    public static final Integer CLAZZ = 1;    public static final Integer BOOK = 2;    // 其他類型}// 創建訂單的請求對象@Data@ApiModel(description = "創建單個訂單")class CreateOrderRequest {    @ApiModelProperty(value = "產品類型")    private Integer productType;    @ApiModelProperty(value = "產品id")    private Integer productId;    @ApiModelProperty(value = "數量")    private Integer amount;}

對應的 Swagger 如下:pIj28資訊網——每日最新資訊28at.com

圖片圖片pIj28資訊網——每日最新資訊28at.com

由于類型定義為 Integer, 所以當輸入非法值(ProductTypes 定義之外的值)時,系統仍舊能接受并執行后續流程,這就是最核心的問題所在,如下圖所示:pIj28資訊網——每日最新資訊28at.com

圖片圖片pIj28資訊網——每日最新資訊28at.com

==商品類型(ProductType)在系統中是一個字典,有自己的固定取值范圍==,定義為 Integer 將放大可接受的值,一旦值在 ProductType 之外便會發生系統異常。pIj28資訊網——每日最新資訊28at.com

2. 解決方案

針對這個案例,小艾可以基于 ProductTypes 中定義的常量對所有入參進行校驗,并在接入文檔中進行強調。但,隨著系統的發展肯定會加入更多的流程,在新流程中產生遺漏就又會出現同樣的問題,那終極解決方案是什么?pIj28資訊網——每日最新資訊28at.com

將 ProductType 可接受的取值范圍與類型的取值范圍保存一致!!!pIj28資訊網——每日最新資訊28at.com

圖片圖片pIj28資訊網——每日最新資訊28at.com

這正是枚舉重要的應用場景。pIj28資訊網——每日最新資訊28at.com

【原則】規范、流程 在沒有檢測機制相輔助時都不可靠。如有可能,請使用編譯器進行強制約束!!!pIj28資訊網——每日最新資訊28at.com

2.1. 枚舉基礎知識

關鍵詞 enum 可以將一組具名值的有限集合創建成一種新的類型,而這些具名的值可以作為常規程序組件使用。pIj28資訊網——每日最新資訊28at.com

枚舉最常見的用途便是==替換常量定義==,為其增添類型約束,完成編譯時類型驗證。pIj28資訊網——每日最新資訊28at.com

2.1.1 枚舉定義

枚舉的定義與類和常量定義非常類似。使用 enum 關鍵字替換 class 關鍵字,然后在 enum 中定義“常量”即可。pIj28資訊網——每日最新資訊28at.com

對于 ProductType 枚舉方案如下:pIj28資訊網——每日最新資訊28at.com

// 定義public enum ProductType {    CLAZZ, BOOK;}public class OrderItem{    private ProductType productType;}

getProductType 和 setProductType 所需類型為 ProductType,不在是比較寬泛的 Integer。在使用的時候可以通過 ProductType.XXX 的方式獲取對應的枚舉值,這樣對類型有了更強的限制。pIj28資訊網——每日最新資訊28at.com

2.1.2. 枚舉的單例性

枚舉值具有單例性,及枚舉中的每個值都是一個單例對象,可以直接使用 == 進行等值判斷。pIj28資訊網——每日最新資訊28at.com

枚舉是定義單例對象最簡單的方法。pIj28資訊網——每日最新資訊28at.com

2.1.3. name 和 ordrial

對于簡單的枚舉,存在兩個維度,一個是name,即為定義的名稱;一個是ordinal,即為定義的順序。pIj28資訊網——每日最新資訊28at.com

圖片圖片pIj28資訊網——每日最新資訊28at.com

簡單測試如下:pIj28資訊網——每日最新資訊28at.com

@Testpublic void nameTest(){    for (ProductType productType : ProductType.values()){        // 枚舉的name維度        String name = productType.name();        System.out.println("ProductType:" + name);        // 通過name獲取定義的枚舉        ProductType productType1 = ProductType.valueOf(name);        System.out.println(productType == productType1);    }}

輸出結果為:pIj28資訊網——每日最新資訊28at.com

ProductType:CLAZZtrueProductType:BOOKtrue

ordrial測試如下:pIj28資訊網——每日最新資訊28at.com

@Testpublic void ordinalTest(){    for (ProductType productType : ProductType.values()){        // 枚舉的ordinal維度        int ordinal = productType.ordinal();        System.out.println("ProductType:" + ordinal);        // 通過ordinal獲取定義的枚舉        ProductType productType1 = ProductType.values()[ordinal];        System.out.println(productType == productType1);    }}

輸出結果如下:pIj28資訊網——每日最新資訊28at.com

ProductType:0trueProductType:1true

從輸出上可以清晰的看出:pIj28資訊網——每日最新資訊28at.com

  1. name 是我們在枚舉中定義變量的名稱
  2. ordrial 是我們在枚舉中定義變量的順序

2.1.4. 枚舉的本質

enum可以理解為編譯器的語法糖,在創建 enum 時,編譯器會為你生成一個相關的類,這個類繼承自 java.lang.Enum。pIj28資訊網——每日最新資訊28at.com

先看下Enum提供了什么:pIj28資訊網——每日最新資訊28at.com

public abstract class Enum<E extends Enum<E>>        implements Comparable<E>, Serializable {    // 枚舉的Name維度    private final String name;    public final String name() {        return name;    }    // 枚舉的ordinal維度    private final int ordinal;    public final int ordinal() {        return ordinal;    }    // 枚舉構造函數    protected Enum(String name, int ordinal) {        this.name = name;        this.ordinal = ordinal;    }    /**     * 重寫toString方法, 返回枚舉定義名稱     */    public String toString() {        return name;    }    // 重寫equals,由于枚舉對象為單例,所以直接使用==進行比較    public final boolean equals(Object other) {        return this==other;    }    // 重寫hashCode    public final int hashCode() {        return super.hashCode();    }    /**     * 枚舉為單例對象,不允許clone     */    protected final Object clone() throws CloneNotSupportedException {        throw new CloneNotSupportedException();    }    /**     * 重寫compareTo方法,同種類型按照定義順序進行比較     */    public final int compareTo(E o) {        Enum<?> other = (Enum<?>)o;        Enum<E> self = this;        if (self.getClass() != other.getClass() && // optimization            self.getDeclaringClass() != other.getDeclaringClass())            throw new ClassCastException();        return self.ordinal - other.ordinal;    }    /**     * 返回定義枚舉的類型     */    @SuppressWarnings("unchecked")    public final Class<E> getDeclaringClass() {        Class<?> clazz = getClass();        Class<?> zuper = clazz.getSuperclass();        return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;    }    /**     * 靜態方法,根據name獲取枚舉值     * @since 1.5     */    public static <T extends Enum<T>> T valueOf(Class<T> enumType,                                                String name) {        T result = enumType.enumConstantDirectory().get(name);        if (result != null)            return result;        if (name == null)            throw new NullPointerException("Name is null");        throw new IllegalArgumentException(            "No enum constant " + enumType.getCanonicalName() + "." + name);    }    protected final void finalize() { }    /**     * 枚舉為單例對象,禁用反序列化     */    private void readObject(ObjectInputStream in) throws IOException,        ClassNotFoundException {        throw new InvalidObjectException("can't deserialize enum");    }    private void readObjectNoData() throws ObjectStreamException {        throw new InvalidObjectException("can't deserialize enum");    }}

從 Enum 中我們可以得到:pIj28資訊網——每日最新資訊28at.com

  1. Enum 中對 name 和 ordrial(final)的屬性進行定義,并提供構造函數進行初始化
  2. 重寫了equals、hashCode、toString方法,其中toString方法默認返回 name
  3. 實現了Comparable 接口,重寫 compareTo,使用枚舉定義順序進行比較
  4. 實現了Serializable 接口,并重寫禁用了clone、readObject 等方法,以保障枚舉的單例性
  5. 提供 valueOf 方法使用反射機制,通過name獲取枚舉值

到此已經解釋了枚舉類的大多數問題,ProductType.values(), ProductType.CLAZZ, ProductType.BOOK,又是從怎么來的呢?這些是編譯器為其添加的。pIj28資訊網——每日最新資訊28at.com

@Testpublic void enumTest(){    System.out.println("Fields");    for (Field field : ProductType.class.getDeclaredFields()){        field.getModifiers();        StringBuilder fieldBuilder = new StringBuilder();        fieldBuilder.append(Modifier.toString(field.getModifiers()))                .append(" ")                .append(field.getType())                .append(" ")                .append(field.getName());        System.out.println(fieldBuilder.toString());    }    System.out.println();    System.out.println("Methods");    for (Method method : ProductType.class.getDeclaredMethods()){        StringBuilder methodBuilder = new StringBuilder();        methodBuilder.append(Modifier.toString(method.getModifiers()));        methodBuilder.append(method.getReturnType())                .append(" ")                .append(method.getName())                .append("(");        Parameter[] parameters = method.getParameters();        for (int i=0; i< method.getParameterCount(); i++){            Parameter parameter = parameters[i];            methodBuilder.append(parameter.getType())                    .append(" ")                    .append(parameter.getName());            if (i != method.getParameterCount() -1) {                    methodBuilder.append(",");            }        }        methodBuilder.append(")");        System.out.println(methodBuilder);    }}

我們分別對 ProductType 中的屬性和方法進行打印,結果如下:pIj28資訊網——每日最新資訊28at.com

Fieldspublic static final class com.example.enumdemo.ProductType CLAZZpublic static final class com.example.enumdemo.ProductType BOOKprivate static final class [Lcom.example.enumdemo.ProductType; $VALUESMethodspublic staticclass [Lcom.example.enumdemo.ProductType; values()public staticclass com.example.enumdemo.ProductType valueOf(class java.lang.String arg0)

從輸出,我們可知編譯器為我們添加了以下幾個特性:pIj28資訊網——每日最新資訊28at.com

  1. 針對每一個定義的枚舉值,添加一個同名的 public static final 的屬性
  2. 添加一個private static final <pre>不能識別此Latex公式: VALUES 屬性記錄枚舉中所有的值信息
  3. 添加一個靜態的 values 方法,返回枚舉中所有的值信息(</pre>VALUES)
  4. 添加一個靜態的 valueOf 方法,用于通過 name 獲取枚舉值(調用 Enum 中的 valueOf 方法)

2.2. 修復方案

了解枚舉的基礎知識后,落地方案也就變的非常簡單,只需:pIj28資訊網——每日最新資訊28at.com

  • 構建一個枚舉類 ProductType,將所有支持的類型添加到枚舉中;
  • 將原來 OrderItem 中的 productType 從原來的 Integer 替換為 ProductType;

具體代碼如下:pIj28資訊網——每日最新資訊28at.com

// 將產品類型定義為 枚舉public enum ProductType {    CLAZZ, BOOK; // 定義系統所支持的類型}// 領域對象中直接使用 ProductType 枚舉public class OrderItem{    // 將原來的 Integer 替換為 ProductType    private ProductType productType;}// 創建單個訂單的請求對象@Data@ApiModel(description = "創建單個訂單")class CreateOrderRequest {    @ApiModelProperty(value = "產品類型")    private ProductType productType;    @ApiModelProperty(value = "產品id")    private Integer productId;    @ApiModelProperty(value = "數量")    private Integer amount;}

新的 Swagger 如下:pIj28資訊網——每日最新資訊28at.com

圖片圖片pIj28資訊網——每日最新資訊28at.com

可見,ProductType 被定義為枚舉類型,并直接給出了全部備選項。pIj28資訊網——每日最新資訊28at.com

3. 更多應用場景

枚舉的核心是==具有固定值的集合==,非常適用于各種類型(Type)、狀態(Status) 這些場景,所以在系統中看到 Type、Status、State 等關鍵字時,需要慎重考慮是否可以使用枚舉。pIj28資訊網——每日最新資訊28at.com

但,枚舉作為一種特殊的類,也為很多場景提供了更優雅的解決方案。pIj28資訊網——每日最新資訊28at.com

3.1. Switch

在Java 1.5之前,只有一些簡單類型(int,short,char,byte)可以用于 switch 的 case 語句,我們習慣采用 ‘常量+case’ 的方式增加代碼的可讀性,但是丟失了類型系統的校驗。由于枚舉的 ordinal 特性的存在,可以將其用于case語句。pIj28資訊網——每日最新資訊28at.com

public class FruitConstant {    public static final int APPLE = 1;    public static final int BANANA = 2;    public static final int PEAR = 3;}// 沒有類型保障public String nameByConstant(int fruit){    switch (fruit){        case FruitConstant.APPLE:            return "蘋果";        case FruitConstant.BANANA:            return "香蕉";        case FruitConstant.PEAR:            return "梨";    }    return "未知";}// 使用枚舉public enum FruitEnum {    APPLE,    BANANA,    PEAR;}// 有類型保障public String nameByEnum(FruitEnum fruit){    switch (fruit){        case APPLE:            return "蘋果";        case BANANA:            return "香蕉";        case PEAR:            return "梨";    }    return "未知";}

3.2. 單例

Java中單例的編寫主要有餓漢式、懶漢式、靜態內部類等幾種方式(雙重鎖判斷存在缺陷),但還有一種簡單的方式是基于枚舉的單例。pIj28資訊網——每日最新資訊28at.com

public interface Converter<S, T> {    T convert(S source);}// 每一個枚舉值都是一個單例對象public enum Date2StringConverters implements Converter<Date, String>{    yyyy_MM_dd("yyyy-MM-dd"),    yyyy_MM_dd_HH_mm_ss("yyyy-MM-dd HH:mm:ss"),    HH_mm_ss("HH:mm:ss");    private final String dateFormat;    Date2StringConverters(String dateFormat) {        this.dateFormat = dateFormat;    }    @Override    public String convert(Date source) {        return new SimpleDateFormat(this.dateFormat).format(source);    }}public class ConverterTests {    private final Converter<Date, String> converter1 = Date2StringConverters.yyyy_MM_dd;    private final Converter<Date, String> converter2 = Date2StringConverters.yyyy_MM_dd_HH_mm_ss;    private final Converter<Date, String> converter3 = Date2StringConverters.HH_mm_ss;    public void formatTest(Date date){        System.out.println(converter1.convert(date));        System.out.println(converter2.convert(date));        System.out.println(converter3.convert(date));    }}

3.3. 狀態機

狀態機是解決業務流程中的一種有效手段,而枚舉的單例性,為構建狀態機提供了便利。pIj28資訊網——每日最新資訊28at.com

以下是一個訂單的狀態扭轉流程,所涉及的狀態包括 Created、Canceled、Confirmed、Overtime、Paied;所涉及的動作包括cancel、confirm、timeout、pay。pIj28資訊網——每日最新資訊28at.com

graph TBNone{開始}--> |create|CreatedCreated-->|confirm|ConfirmedCreated-->|cancel|CanceldConfirmed-->|cancel|CanceldConfirmed-->|timeout|OvertimeConfirmed-->|pay| Paied
// 狀態操作接口,管理所有支持的動作public interface IOrderState {    void cancel(OrderStateContext context);    void confirm(OrderStateContext context);    void timeout(OrderStateContext context);    void pay(OrderStateContext context);}// 狀態機上下文public interface OrderStateContext {    void setStats(OrderState state);}// 訂單實際實現public class Order{    private OrderState state;    private void setStats(OrderState state) {        this.state = state;    }    // 將請求轉發給狀態機    public void cancel() {        this.state.cancel(new StateContext());    }    // 將請求轉發給狀態機    public void confirm() {        this.state.confirm(new StateContext());    }    // 將請求轉發給狀態機    public void timeout() {        this.state.timeout(new StateContext());    }    // 將請求轉發給狀態機    public void pay() {        this.state.pay(new StateContext());    }    // 內部類,實現OrderStateContext,回寫Order的狀態    class StateContext implements OrderStateContext{        @Override        public void setStats(OrderState state) {            Order.this.setStats(state);        }    }}// 基于枚舉的狀態機實現public enum OrderState implements IOrderState{    CREATED{        // 允許進行cancel操作,并把狀態設置為CANCELD        @Override        public void cancel(OrderStateContext context){            context.setStats(CANCELD);        }        // 允許進行confirm操作,并把狀態設置為CONFIRMED        @Override        public void confirm(OrderStateContext context) {            context.setStats(CONFIRMED);        }    },    CONFIRMED{        // 允許進行cancel操作,并把狀態設置為CANCELD        @Override        public void cancel(OrderStateContext context) {            context.setStats(CANCELD);        }        // 允許進行timeout操作,并把狀態設置為OVERTIME        @Override        public void timeout(OrderStateContext context) {            context.setStats(OVERTIME);        }        // 允許進行pay操作,并把狀態設置為PAIED        @Override        public void pay(OrderStateContext context) {            context.setStats(PAIED);        }    },    // 最終狀態,不允許任何操作    CANCELD{    },    // 最終狀態,不允許任何操作    OVERTIME{    },    // 最終狀態,不允許任何操作    PAIED{    };    @Override    public void cancel(OrderStateContext context) {        throw new NotSupportedException();    }    @Override    public void confirm(OrderStateContext context) {        throw new NotSupportedException();    }    @Override    public void timeout(OrderStateContext context) {        throw new NotSupportedException();    }    @Override    public void pay(OrderStateContext context) {        throw new NotSupportedException();    }}

3.4. 責任鏈

在責任鏈模式中,程序可以使用多種方式來處理一個問題,然后把他們鏈接起來,當一個請求進來后,他會遍歷整個鏈,找到能夠處理該請求的處理器并對請求進行處理。pIj28資訊網——每日最新資訊28at.com

枚舉可以實現某個接口,加上其天生的單例特性,可以成為組織責任鏈處理器的一種方式。pIj28資訊網——每日最新資訊28at.com

// 消息類型public enum MessageType {    TEXT, BIN, XML, JSON;}// 定義的消息體@Valuepublic class Message {    private final MessageType type;    private final Object object;    public Message(MessageType type, Object object) {        this.type = type;        this.object = object;    }}// 消息處理器public interface MessageHandler {    boolean handle(Message message);}
// 基于枚舉的處理器管理public enum MessageHandlers implements MessageHandler{    TEXT_HANDLER(MessageType.TEXT){        @Override        boolean doHandle(Message message) {            System.out.println("text");            return true;        }    },    BIN_HANDLER(MessageType.BIN){        @Override        boolean doHandle(Message message) {            System.out.println("bin");            return true;        }    },    XML_HANDLER(MessageType.XML){        @Override        boolean doHandle(Message message) {            System.out.println("xml");            return true;        }    },    JSON_HANDLER(MessageType.JSON){        @Override        boolean doHandle(Message message) {            System.out.println("json");            return true;        }    };    // 接受的類型    private final MessageType acceptType;    MessageHandlers(MessageType acceptType) {        this.acceptType = acceptType;    }    // 抽象接口    abstract boolean doHandle(Message message);    // 如果消息體是接受類型,調用doHandle進行業務處理    @Override    public boolean handle(Message message) {        return message.getType() == this.acceptType && doHandle(message);    }}
// 消息處理鏈public class MessageHandlerChain {    public boolean handle(Message message){        for (MessageHandler handler : MessageHandlers.values()){            if (handler.handle(message)){                return true;            }        }        return false;    }}

3.5. 分發器

分發器根據輸入的數據,找到對應的處理器,并將請求轉發給處理器進行處理。 由于 EnumMap 其出色的性能,特別適合根據特定類型作為分發策略的場景。pIj28資訊網——每日最新資訊28at.com

// 消息體@Valuepublic class Message {    private final MessageType type;    private final Object data;    public Message(MessageType type, Object data) {        this.type = type;        this.data = data;    }}// 消息類型public enum MessageType {    // 登錄    LOGIN,    // 進入房間    ENTER_ROOM,    // 退出房間    EXIT_ROOM,    // 登出    LOGOUT;}// 消息處理器public interface MessageHandler {    void handle(Message message);}
// 基于EnumMap的消息分發器public class MessageDispatcher {    private final Map<MessageType, MessageHandler> dispatcherMap =             new EnumMap<MessageType, MessageHandler>(MessageType.class);    public MessageDispatcher(){        dispatcherMap.put(MessageType.LOGIN, message -> System.out.println("Login"));        dispatcherMap.put(MessageType.ENTER_ROOM, message -> System.out.println("Enter Room"));        dispatcherMap.put(MessageType.EXIT_ROOM, message -> System.out.println("Exit Room"));        dispatcherMap.put(MessageType.LOGOUT, message -> System.out.println("Logout"));    }    public void dispatch(Message message){        MessageHandler handler = this.dispatcherMap.get(message.getType());        if (handler != null){            handler.handle(message);        }    }}

4. 示例&源碼

倉庫地址:https://gitee.com/litao851025/learnFromBug/pIj28資訊網——每日最新資訊28at.com

代碼地址:https://gitee.com/litao851025/learnFromBug/tree/master/src/main/java/com/geekhalo/demo/enums/limitpIj28資訊網——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-41674-0.html【故障現場】控制好取值范圍,甭給別人犯錯的機會

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 昇騰 AI 開發者創享日?廣州站成功舉辦 四大儀式激發人工智能產業創新活力

下一篇: 聊聊分布式數據庫TDSQL的技術架構

標簽:
  • 熱門焦點
  • 對標蘋果的靈動島 華為帶來實況窗功能

    繼蘋果的靈動島之后,華為也在今天正式推出了“實況窗”功能。據今天鴻蒙OS 4.0的現場演示顯示,華為的實況窗可以更高效的展現出實時通知,比如鎖屏上就能看到外賣、打車、銀行
  • 把LangChain跑起來的三個方法

    使用LangChain開發LLM應用時,需要機器進行GLM部署,好多同學第一步就被勸退了,那么如何繞過這個步驟先學習LLM模型的應用,對Langchain進行快速上手?本片講解3個把LangChain跑起來
  • 多線程開發帶來的問題與解決方法

    使用多線程主要會帶來以下幾個問題:(一)線程安全問題  線程安全問題指的是在某一線程從開始訪問到結束訪問某一數據期間,該數據被其他的線程所修改,那么對于當前線程而言,該線程
  • 在線圖片編輯器,支持PSD解析、AI摳圖等

    自從我上次分享一個人開發仿造稿定設計的圖片編輯器到現在,不知不覺已過去一年時間了,期間我經歷了裁員失業、面試找工作碰壁,寒冬下一直沒有很好地履行計劃.....這些就放在日
  • 深度探索 Elasticsearch 8.X:function_score 參數解讀與實戰案例分析

    在 Elasticsearch 中,function_score 可以讓我們在查詢的同時對搜索結果進行自定義評分。function_score 提供了一系列的參數和函數讓我們可以根據需求靈活地進行設置。近期
  • 一文掌握 Golang 模糊測試(Fuzz Testing)

    模糊測試(Fuzz Testing)模糊測試(Fuzz Testing)是通過向目標系統提供非預期的輸入并監視異常結果來發現軟件漏洞的方法。可以用來發現應用程序、操作系統和網絡協議等中的漏洞或
  • 電視息屏休眠仍有網絡上傳 愛奇藝被質疑“薅消費者羊毛”

    記者丨寧曉敏 見習生丨汗青出品丨鰲頭財經(theSankei) 前不久,愛奇藝發布了一份亮眼的一季報,不僅營收和會員營收創造歷史最佳表現,其運營利潤也連續6個月實現增長。自去年年初
  • 三星折疊屏手機去年銷售近1000萬臺 今年目標定為1500萬

    7月29日消息,三星率先發力可折疊手機市場,在全球市場已經取得了非常亮眼的成績,接下來會進一步鞏固和擴大這一優勢。三星在推出Galaxy Z Flip5和Galax
  • 電博會與軟博會實現"線下+云端"的雙線融合

    在本次“電博會”與“軟博會”雙展會利好條件的加持下,既可以發揮展會拉動人流、信息流、資金流實現快速交互流動的作用,繼而推動區域經濟良性發展;又可以聚
Top