Include Sticky Posts with Custom Query

$sticky = get_option( 'sticky_posts' );

$args = array(
  'post_type'           => 'post' ,
  'orderby'             => 'date' ,
  'order'               => 'DESC' ,
  'posts_per_page'      => 4,
  'cat'                 => '3',
  'paged'               => get_query_var('paged'),
  'post__in'            => isset( $sticky[0] ) ? $sticky[0] : array(),
  'ignore_sticky_posts' => 1,
  
); 
$q = new WP_Query($args);

The above code will include only the first sticky post and if it does not exist, it will get normal posts.

If you want to show all of the existing sticky posts, then use the following code:

$args = array(
  'post_type'           => 'post' ,
  'orderby'             => 'date' ,
  'order'               => 'DESC' ,
  'posts_per_page'      => 4,
  'cat'                 => '3',
  'paged'               => get_query_var('paged'),
  'ignore_sticky_posts' => false,
  
); 
$q = new WP_Query($args);