Pure dry goods sharing! Summary of 2020 Ali Java Post Written Test Interview Questions (with answers)

Preface

The 2020 Golden Nine and Silver Ten will end soon. Now I have compiled the summary of the interview questions of Ali for the Golden Nine and Silver Ten interviews. They are all the real interview questions I got from my friends. Not much to say, I will share with you all the dry goods!

Is int a=10 an atomic operation?

Yes.
 be careful:

  • i++ (or ++i) is a non-atomic operation, i++ is a multi-step operation and can be interrupted. i++ can be divided into 3 steps, the first step reads the value of i, the second step calculates i+1; the third step assigns the final value to i.
     * int a = b; is not an atomic operation. From the grammatical level, this is also a statement, which is atomic; but from the actual execution of the binary instructions, due to the limitations of the CPU architecture of modern computers, data cannot be directly transferred from memory to another memory. Register interrupt, this statement generally corresponds to two computer instructions, that is, to move the value of variable b to a register (such as eax), and then from the register to the memory address of variable a:
mov eax, dword ptr [b]  
mov dword ptr [a], eax 

Since there are two instructions, when multiple threads execute these two instructions, a certain thread may be deprived of the CPU time slice after the first instruction is executed, and switch to another thread, resulting in uncertainty.

Does innodb support full-text indexing?

After version 5.6, the InnoDB storage engine began to support full-text indexing. After version 5.7, it began to support Chinese through the use of the ngram plugin. Previously, only English was supported, because spaces were used as word separators, which was not suitable for Chinese. MySQL allows the establishment of full-text indexes on char, varchar, and text types.

Does innodb support table locks?

Support, supplement: ordinary additions, deletions, and modifications are table locks, and additions, deletions, and modifications added to indexes are row locks. No locks are added when executing queries.

How does HTTP short connection become long connection.

Add --Connection:keep-alive in the header.

Will calling yeild() block?

 Blocking refers to suspending the execution of a thread to wait for a certain condition (such as a resource to be ready).
Yield() method: yield() makes the thread give up the currently allocated CPU time, but does not block the thread, that is, the thread is still in an executable state and may be allocated CPU time again at any time. The effect of calling yield() is equivalent to the fact that the scheduler thinks that the thread has executed enough time to switch to another thread. Yield() just makes the current thread return to the executable state, so the thread that executes yield() may be executed immediately after entering the executable state. sleep() allows threads with low priority to get a chance to execute, of course, it also allows threads with the same priority and high priority to have a chance to execute; yield() can only give threads of the same priority a chance to execute.

Is the virtual machine stack shared by threads?

 It's not.
Pure dry goods sharing!  Summary of 2020 Ali Java Post Written Test Interview Questions (with answers)

 When the JVM initially runs, it will allocate Method Area and Heap, and every time the JVM encounters a thread, it will allocate a Program Counter Register, VM Stack and Native. Method Stack (local method stack), when the thread terminates, the memory space occupied by the three (virtual machine stack, local method stack, and program counter) will also be released. This is why I divide the memory area into thread sharing and non-thread sharing. The life cycle of the three non-thread sharing areas is the same as that of the thread, and the thread shared area is the same as the life cycle of the JAVA program, so this It is also the reason why the system garbage collection only occurs in the area shared by threads (in fact, it only occurs on Heap for most virtual machines).

Stack area:
  • Each thread contains a stack area, and only the value of the basic data type is saved in the stack (for example, 1 in int i=1 is the object of the basic type) and the reference of the object and the reference of the basic data
  • The data (basic data types and object references) in each stack are private and cannot be accessed by other stacks.
  • The stack is divided into 3 parts: basic type variable area, execution environment context, operation instruction area (store operation instructions).
Heap area:
  • All objects stored are objects, and each object contains information about a corresponding class. (The purpose of class is to get operation instructions)
  • Jvm has only one heap area shared by all threads. Basic types and object references are not stored in the heap, only the object itself.
Method area:
  • Also called static area, like heap, it is shared by all threads. The method area contains all the class and static variables.
  • The method area contains elements that are always unique in the entire program, such as class and static variables. (The difference between the two is that the heap area stores new object information, and the method area stores its own class information)

Where are the constants stored in the JVM?

Method area: Also called static area, like heap, it is shared by all threads. It is used to store data such as class information, constants, static variables, and code compiled by the just-in-time compiler that have been loaded by the virtual machine.

The window.postMessage() method can safely implement cross-origin communication. Generally, for scripts on two different pages, only when the page that executes them is located with the same protocol (usually https), port number (443 is the default value of https), and host (the modulus of the two pages Document.domain When set to the same value), the two scripts can communicate with each other. The window.postMessage() method provides a controlled mechanism to circumvent this restriction. As long as it is used correctly, this method is safe.

Are all objects allocated to the heap?

      Answer: Not necessarily.

Is CopyOnWriteArrayList thread safe?

 Answer: Yes.
 CopyOnWriteArrayList uses a method called copy-on-write. When a new element is added to CopyOnWriteArrayList, a copy is first copied from the original array, and then the new array is written. After writing, the original The array reference points to the new array. Create a new array and add a new element to the new array. At this time, the reference to array still points to the original array. ​​​​​​​When the element is successfully added to the new array, point the reference of array to the new array.
      The entire add operation of CopyOnWriteArrayList is performed under the protection of the lock. This is done to avoid making multiple copies when multi-threaded concurrent add, messing up the data, resulting in the final array data not what we expected.

    public boolean add(E e) {
        //1、先加锁
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            Object[] elements = getArray();
            int len = elements.length;
            //2、拷贝数组
            Object[] newElements = Arrays.copyOf(elements, len + 1);
            //3、将元素加入到新数组中
            newElements[len] = e;
            //4、将array引用指向到新数组
            setArray(newElements);
            return true;
        } finally {
            //5、解锁
            lock.unlock();
        }
    }

Since all write operations are performed on the new array, if there are concurrent threads writing at this time, it is controlled by locks. If there are concurrent threads reading, there are several situations:

  • If the write operation is not completed, then directly read the data of the original array;
  • If the write operation is completed, but the reference has not yet pointed to the new array, then the original array data is also read;
  • If the write operation is complete, and the reference already points to the new array, then the data is read directly from the new array.

It can be seen that the read operation of CopyOnWriteArrayList can be done without locking.
CopyOnWriteArrayList has several disadvantages:
because the array needs to be copied during the write operation, it will consume memory.
If the content of the original array is relatively large, it may cause the young gc or full gc to
not be used for real-time reading scenarios, such as copying arrays, It takes time to add new elements,
so after calling a set operation, the read data may still be old.
Although CopyOnWriteArrayList can achieve final consistency, it still cannot meet the real-time requirements;
CopyOnWriteArrayList is suitable for scenarios where there are more reads and less writes. However, this kind of caution is used
because no one can guarantee how much data will be placed in CopyOnWriteArrayList. In
case the data is a little too much, the array must be copied every time add/set, this cost is too high.
In high-performance Internet applications, this kind of operation causes failures in minutes.
The idea revealed by CopyOnWriteArrayList

  • Separate reading and writing, separate reading and writing
  • Final consistency
  • Use other ideas to open up space to resolve concurrency conflicts​​​​​​​

Array out of bounds problem

Generally speaking, when we use it, we use one thread to add elements to the container and one thread to read the elements, and the read operations tend to be more frequent. Write operation locks to ensure thread safety, and read-write separation ensures the efficiency of read operations, which is perfect.
If there is a third thread to delete an element at this time, the reader thread reads the last element in the container. Before reading, the container size is i. When reading, the delete thread suddenly deletes an element. At this time, the container size It becomes i-1, and the reader thread still reads the i-th element. At this time, the array is out of bounds.
To test it, first stuff 10,000 test data into CopyOnWriteArrayList, start two threads, one continuously deletes elements, and the other continuously reads the last data in the container.

    public void test(){
        for(int i = 0; i<10000; i++){
            list.add("string" + i);
        }

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    if (list.size() > 0) {
                        String content = list.get(list.size() - 1);
                    }else {
                        break;
                    }
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    if(list.size() <= 0){
                        break;
                    }
                    list.remove(0);
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

Pure dry goods sharing!  Summary of 2020 Ali Java Post Written Test Interview Questions (with answers)

Can Java interfaces have multiple inheritance?

 The java class is single inheritance. classB extends classA
java interface can be inherited more. Interface3 extends Interface0, Interface1, interface...
The main reason for disallowing multiple inheritance of classes is that if A inherits both B and C, and B and C have a D method at the same time, how does A decide which one to inherit?
 But there is no such problem with interfaces. It doesn't matter if all interfaces inherit from abstract methods, so interfaces can inherit multiple interfaces.

(byte)300==(byte)100+(short)200?

Answer: false.
The value range of byte in java is -128~127, when overflow and underflow occur, modulo 256; 130>127 overflows, so modulo 256 will result in 130, still overflow, and then minus 256 will get -126, so s=-126 .300>127 overflows, so the modulus 256 gets 44 and 44 within the byte value range, so s=44.
The binary value of 300 is: 100101100; after byte forced conversion, 8 bits from right to left are: 00101100; The eight bits are 0, so it is a positive number, and we know that the original inverse complement of a positive number is the same; therefore, the conversion of 00101100 to decimal is: 44 (32+8+4)
 (byte)100+(short)200, byte and short The result will be automatically converted to short without overflow. So (byte)100+(short)200=(short)300, and the result of (byte)300 is 44. That is, the two are not equal.

The operating system has the functions of process management, storage management, file management and device management. Which one of the following descriptions is incorrect? (A)

A. Process management is mainly to manage programs.
B. Storage management is mainly to manage memory resources
. C. File management can effectively support file operations and solve file sharing, confidentiality and protection issues
. D. Device management refers to the computer system except for CPU Management of all input and output devices other than memory

This and super are correct (C):

A. Both can be used in the main() method. B. Both refer to a memory address. 
C. Cannot be used in the main() method. D. The same meaning.
public static void main(String[] args), the main method is a static method. You cannot use the object-specific this or super keywords.

Is reference counting a JVM GC algorithm?

Answer: Yes.

Can an exception be thrown again in the finally{} of the try{}catch(){}finally{} structure?

 答:能。
Exception in thread “main” java.lang.Exception: 异常4
at com.test.FinallyTry.f(FinallyTry.java:16)
at com.test.FinallyTry.main(FinallyTry.java:5)

--------Throwing an exception or return in finally will cover up the previous exception

What's new in HTTP2?

Answer: Reduce the size of the header, add request priority, server push, and multiplexing.

Can index change random IO into sequential IO?

 answer.
Random IO: Assuming that the data we need is randomly scattered in different sectors of different pages of the disk, then to find the corresponding data, we need to wait until the magnetic arm (addressing function) rotates to the specified page, and then the disk finds the corresponding In order to find a piece of data we need, the process is performed in turn until all the data is found. This is random IO, and the data reading speed is slow.
Sequential IO: Assuming that we have found the first piece of data, and other required data is just behind this piece of data, then there is no need to re-address, and we can get the data we need in turn. This is called sequential IO.

Is the transient modified variable a temporary variable?

answer.

  • Once the variable is modified transiently, the variable will no longer be part of the object's persistence, and the variable content cannot be accessed after serialization.
  • The transient keyword can only modify variables, not methods and classes. Note that local variables cannot be modified by the transient keyword. If the variable is a user-defined class variable, the class needs to implement the SERIALIZABLE interface.
  • Variables modified by the transient keyword can no longer be serialized, and a static variable cannot be serialized regardless of whether it is modified by transient.
          Note: In Java, the serialization of objects can be achieved by implementing two interfaces. If the implementation is the SERIALIZABLE interface, all serialization will be carried out automatically, if the implementation is the Externalizable interface, nothing can be automatic For serialization, you need to manually specify the variable to be serialized in the writeExternal method, which has nothing to do with whether it is modified by transient.

High, medium and low three-level scheduling.

 Advanced scheduling: Job scheduling, according to a certain strategy, the program on the selected disk is loaded into the memory, and the process is established. (Exist in multi-channel batch processing system)
  Intermediate scheduling: exchange scheduling, data exchange between internal and external storage according to a certain strategy.
Low-level scheduling: CPU scheduling (process scheduling), select the ready process according to a certain strategy, and occupy the cpu for execution.
 Among them, low-level scheduling is necessary.

The next one to check whether port 80 is occupied?

  • Method 1: ps -ef |grep 80
  •  Method 2: netstat -anp |grep :80
  •  Way three: lsof -i:80
  •  Method 4: netstat -tunlp |grep :80
  •  Method five: netstat -an |grep :80

What is the C++ weak reference pointer?

 weak_ptr is also a reference-counting smart pointer, but it does not increase the reference count of the object, that is, weak reference. In contrast, shared_ptr is a strong reference. As long as there is a shared_ptr pointing to an object, the object will not be destroyed until the last shared_ptr pointing to the object is destroyed or reset().
Using weak_ptr, we can solve common dangling pointer problems and circular reference problems.

The following features that are not part of the class construction method are ().

  • A. No return value
  • B. Users can automatically call through new.
  • C. The constructor name must be the same as the class name
  • D. Users can directly call
  • D [Analysis] The construction method is a special method in the class. It is a method written for the initialization operation of the object. It is used to define the initial state of the object. Every class in the Java language has a constructor, which is also composed of method names, parameters and method bodies. The name of the constructor method must be the same as the class name, it has no return value, and the user cannot call it directly, but can only be called automatically by new.

On which layer does the spx protocol work?

 The SPX (Sequenced Packet Exchange protocol) protocol is a protocol developed by Novell and used in NetWare to ensure the successful transmission of information. SPX uses NetWare's IPX protocol as its delivery mechanism and provides client-server and layer-to-layer interactive communication between network nodes. It works at the transport layer.

Why does TCP wait for 2MSL to disconnect after the fourth wave of hands? Why is the waiting time 2MSL?

  •   Answer: 1. In order to ensure that the last wave of the client can reach the server, if the 4th wave of the message is lost, the server will retransmit the 3rd wave of the message over time, so the client is now Not directly enter CLOSED, but keep TIME_WAIT (waiting for 2MSL is TIME_WAIT). When the client again receives the third wave request from the server due to timeout retransmission, the client will re-send the fourth wave message to the server (to ensure that the server can receive the client's response message). Finally, the client and server are truly disconnected. To put it bluntly, waiting for 2MSL is to ensure that the server can receive the final response from the client.

  * 2. If the client CLOSED directly, and then initiate a new connection to the server again, no one can guarantee that the port number of the newly initiated connection and the connection just closed are different. It is possible that the port numbers of the new and old connections are the same of. Assuming that the port numbers of the new and old connections are the same, if some data of the old connection is still stuck in the network, the remaining data will not reach the server until the new connection is established. In view of the same port numbers before and after, the TCP protocol assumes that these data belong to the new connection, so The data is so messed up. Therefore, the TCP connection has to wait for 2MSL in the TIME_WAIT state to ensure that all the data of the old connection disappears in the network!

  • 3. First explain what MSL is. MSL is the abbreviation of Maximum Segment Lifetime, translated as the maximum survival time of a message, that is, the maximum time any message can survive on the network. Once this time is exceeded, the message will be discarded. 2MSL means twice the time of MSL.
    Why is it 2 times?

  • The side that is actively disconnected is A, and the side that is passively disconnected is B.
  • The first message: A sends FIN
  • The second message: B reply ACK
  •  The third message: B sends FIN at this moment: B unilaterally believes that he and A have reached a consensus, that is, both parties agree to close the connection. At this point, can B release the memory resources occupied by this TCP connection? No, B must ensure that A receives its own ACK and FIN. So B needs to wait quietly for the fourth message from A:
  • The fourth message: A sends an ACK to confirm receipt of B’s FIN

When B receives this message, it is considered that both parties have reached synchronization: both parties know that the connection can be released, and B can safely release the memory resources and port number occupied by the TCP connection. Therefore, the passively closed B does not need any wait time and directly releases the resources. However, A does not know whether B received his own ACK, A
      thinks like this: 1) If B does not receive his own ACK, it will retransmit the FiN overtime, then A will send the ACK again after receiving the retransmitted FIN again
      2) If B receives its own ACK, it will not send any more messages, including
whether the ACK is 1 or 2, A needs to wait, and the maximum waiting time of these two cases should be taken to deal with the worst case. , The worst case is: the
      maximum survival time (MSL) of the ACK message + the maximum survival time (MSL) of the FIN message. This is exactly 2MSL (Maximum Segment Life). Waiting for 2MSL time, A can safely release the resources and port number occupied by TCP. At this time, the port number can be used to connect to any server. It can also ensure that all old links in the network disappear.

What are the status of the process, and briefly describe it?

  • There are five basic states of a process, namely, creation state, ready state, running state, blocking state, and termination state.
  •   Creation status: When a process is created, it needs to apply for a blank PCB, fill in the control and management process information, and complete resource allocation.
  •  Ready state: The process is ready, the required resources have been allocated, and it can run immediately as long as the CPU is allocated.
  •   Execution state: After the process is in the ready state and is scheduled, the process enters the execution state.
  •    Blocking state: The process being executed temporarily cannot run due to certain events, and the process is blocked.
  •  Termination state: The process ends, or an error occurs, or is terminated by the system, enters the termination state, and cannot be executed anymore.
  •  A process refers to a running activity of a program on a certain data set in a computer, and is the basic unit of the system for resource allocation and scheduling.
  • Process state refers to the life cycle of a process can be divided into a set of states, these states describe the entire process, the process state reflects the life state of a process.

Create NIO client code.

package com.cn.niochat;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Scanner;

/**
 * 用Java实现nio的客户端
 */
public class NioClient {

    public void start() throws IOException {
        /**
         * 链接服务器端
         */
        SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1",8000));

        //向服务器端发送数据
        //从命令行获取数据,获取键盘的输入
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextLine()){
            //获取这一行数据
           String request =  scanner.nextLine();
           //如果有数据,则发送,且数据不为空
           if(request != null && request.length() > 0){
               socketChannel.write(Charset.forName("UTF-8").encode(request));
           }
        }
    }

    public static void main(String[] args) throws IOException {
        NioClient nioClient = new NioClient();
        nioClient.start();
    }
}

What are the methods to obtain a class instance of a class?

  • (1). Call the class attribute of the runtime class itself
        Class clazz = String.class;
  • (2) Obtain
        public final Class<?> getClass() through the object of the runtime class is a non-static method.
        Person p = new Person();
        Class clazz = p.getClass();
  • (3) Obtain through the static method of Class: reflect the dynamic nature of reflection
        String className = "java.util.commons";
        Class clazz = Class.forName(className);
  • (4) Through the class loader
        String className = "java.util.commons";
        ClassLoader classLoader = this.getClass().getClassLoader();
        Class claz = classLoader.loadClass(className);

The number of occurrences of the characters a, b, c, d, e, and f are 16, 5, 12, 17, 10, and 25, respectively. What is the minimum number of bytes to encode?

Pure dry goods sharing!  Summary of 2020 Ali Java Post Written Test Interview Questions (with answers)

(25+16+17)×2+12×3+(5+10)×4=212。

What is the best object in MySQL to obtain the record of the result set and perform special operations on this record?

cursor.

System.out.println(1+1+"1") outputs 21. System.out.println("1"+1+1); Output 111.

Java's + expression calculation is from left to right. If it is two integers, it will be evaluated, if one of them is a String, it will be spliced, and the result is String . 1+1+"1", first calculate 1+1, because both are shaping, evaluation=2, then 2+"1", splicing, so it is
21, and "1"+1+1, first calculate "1"+1, because there is a String, the result is "11", and then "11"+1 is "111".

Member variables, static methods look at the left; non-static methods: compile look at the left, run look at the right.

Meaning: when the parent class variable refers to the subclass object (Fu f = new Zi();
), in the object pointed to by the reference variable f, his member variables and static methods are consistent with the parent class, and his non Static methods are consistent with the parent class at compile time, but are consistent with the subclass at runtime (replication occurs).

class Fu {
    intnum = 5;
    static void method4() {
        System.out.println("fu method_4");
    }
    void method3() {
        System.out.println("fu method_3");
    }
}

class Zi extends Fu {
    intnum = 8;
    static void method4() {//注意点:静态方法不能重写
        System.out.println("zi method_4");
    }
    void method3() {
        System.out.println("zi method_3");
    }
}

class DuoTaiDemo4 {

     public static void main(String[] args) {
         Fu f = new Zi();
         System.out.println(f.num);//与父类一致
         f.method4();//与父类一致
         f.method3();//编译时与父类一致,运行时与子类一致
         Zi z = new Zi();
         System.out.println(z.num);
         z.method4();
         z.method3();
     }
}

Http status code starting with 1

  • A status code that represents a temporary response and requires the requester to continue the operation.
  • 100 (Continue) The requester should continue to make the request. The server returns this code to indicate that it has received the first part of the request and is waiting for the rest.
  • 101 (Switching protocol) The requester has asked the server to switch the protocol, and the server has confirmed and is ready to switch.

Http status code starting with 2

  • Indicates that the request was successful
  • 200 The request was successfully processed, and this status code is usually returned;
  • 201 The request was successful and the server created a new resource.
  • 202 The request was accepted but no resource was created;
  • 203 Request to return another resource;
  • 204 The server successfully processed the request, but did not return any content;
  • 205 The server successfully processed the request, but did not return any content;
  • 206 Process part of the request;

3xx (redirect)

  • Redirect code is also a common code
  • 300 (multiple choices) In response to requests, the server can perform multiple operations. The server can select an operation based on the requester (user agent), or provide a list of operations for the requester to choose.
  • 301 (Moved Permanently) The requested page has been permanently moved to a new location. When the server returns this response (response to a GET or HEAD request), it will automatically redirect the requester to the new location.
  • 302 (Temporary move) The server currently responds to requests from web pages in different locations, but the requester should continue to use the original location for future requests.
  • 303 (View other locations) When the requester should use separate GET requests for different locations to retrieve the response, the server returns this code.
  • 304 (Unmodified) The requested webpage has not been modified since the last request. When the server returns this response, the content of the web page will not be returned.
  • 305 (Use proxy) The requester can only use the proxy to access the requested web page. If the server returns this response, it also indicates that the requester should use a proxy.
  • 307 (Temporary redirect) The server currently responds to requests from web pages in different locations, but the requester should continue to use the original location for future requests.

The http status code at the beginning of 4 indicates an error in the request

  • 400 The server does not understand the syntax of the request.
  • 401 request requires authentication. For web pages that require login, the server may return this response.
  • 403 The server rejected the request.
  • 404 The server could not find the requested page.
  • 405 The method specified in the request is disabled.
  • 406 Unable to respond to the requested webpage with the requested content characteristics.
  • 407 This status code is similar to 401, but specifies that the requester should be authorized to use the proxy.
  • 408 The server timed out while waiting for the request.
  • 409 The server encountered a conflict while fulfilling the request. The server must include information about the conflict in the response.
  • 410 If the requested resource has been permanently deleted, the server will return this response.
  • 411 The server does not accept requests without the payload length header field.
  • 412 The server did not meet one of the preconditions set by the requester in the request.
  • 413 The server cannot process the request because the request entity is too large, which exceeds the processing capacity of the server.
  • 414 The requested URI (usually a URL) is too long for the server to process.
  • 415 The requested format is not supported by the requested page.
  • 416 If the page cannot provide the requested range, the server returns this status code.
  • 417 The server did not meet the requirements of the "expected" request header field.

Status codes starting with 5 are not common, but we should know

  • 500 (Server internal error) The server encountered an error and could not complete the request.
  • 501 (Not yet implemented) The server does not have the function to complete the request. For example, the server may return this code when the request method is not recognized.
  • 502 (Bad gateway) The server was acting as a gateway or proxy and received an invalid response from the upstream server.
  • 503 (Service unavailable) The server is currently unavailable (due to overload or maintenance shutdown). Usually, this is only a temporary state.
  • 504 (Gateway timeout) The server is acting as a gateway or proxy, but did not receive a request from the upstream server in time.
  • 505 (HTTP version is not supported) The server does not support the HTTP protocol version used in the request.
  • Memory formula: 1 Pro (temporary response) 20% (request successful) 3 directed (redirect) 4 please (request error) 5 service (server error)

Guess you like

Origin blog.51cto.com/14966465/2542686