Understanding the driver's run phase

Typical Driver component’s run phase is written as ::


 task run_phase(uvm_phase phase);

    forever begin
    
      seq_item_port.get_next_item(req);
 
      @( posedge  vif.clock );

      vif.signal_ip   <=  req.signal_ip ;
      
      //  More  nonblocking  assignments  here  to  drive  stimulus  to  the  DUT  ....
      
      @( posedge  vif.clock );

      //  Sample  the  DUTs  output  corresponding  to  above  stimulus
         req.signal_op  =  vif.signal_op ;
         
      //  More  sampling  via  blocking  assignments  .....
          
      seq_item_port.item_done(req);
          
    end 
  endtask : run_phase


I have a few questions :

(a) Why is nonblocking assignment used to drive interface signals ? Are there disadvantages of using blocking assignment ?

(b) Driver drives stimulus to the DUT exactly on the active edge . Won’t this violate hold time ? ( specially if we consider clock skews )

(c) Driver samples the DUT’s output via blocking assignment exactly on the active edge .
If the DUT were to drive these signals on the same active edge using continuous assignment ( assign ) , won’t this result in a race condition ?

In reply to hisingh:

A testbench is just an abstraction of someone else’s design you are not testing. It needs to follow all the same RTL coding rules to prevent race conditions and timing violations.